/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.api.controller;

import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.UserCache;
import org.springblade.common.constant.CommonConstant;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.api.request.*;
import org.springblade.modules.api.response.TeamResponse;
import org.springblade.modules.api.service.IApiService;
import org.springblade.modules.platform.entity.*;
import org.springblade.modules.platform.service.*;
import org.springblade.modules.platform.vo.UserAddressVO;
import org.springblade.modules.platform.vo.UserBankCardsVO;
import org.springblade.modules.platform.vo.UserRecomVO;
import org.springblade.modules.platform.vo.UserTicketVO;
import org.springblade.modules.platform.wrapper.UserAddressWrapper;
import org.springblade.modules.platform.wrapper.UserBankCardsWrapper;
import org.springblade.modules.platform.wrapper.UserRecomWrapper;
import org.springblade.modules.platform.wrapper.UserTicketWrapper;
import org.springblade.modules.system.entity.Region;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.entity.UserApp;
import org.springblade.modules.system.service.IRegionService;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.UserAppVO;
import org.springblade.modules.system.vo.UserVO;
import org.springblade.modules.system.wrapper.UserWrapper;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;

/**
 * 控制器
 *
 * @author xuwei
 * @since 2022-02-12
 */
@RestController
@AllArgsConstructor
@RequestMapping(CommonConstant.API_URL)
@Api(value = "我的", tags = "04.个人中心")
public class Api04Controller extends BladeController {

	private final IUserAddressService userAddressService;
	private final IUserFeedbacksService userFeedbacksService;
	private final IUserService userService;
	private final IUserRecomService userRecomService;
	private final IUserBankCardsService userBankCardsService;
	private final IUserTicketService userTicketService;
	private final IVersionUpgradeService versionUpgradeService;
	private final IApiService apiService;
	private final IRegionService regionService;
	private final IFreightService freightService;
	private final IUserCardInfoService userCardInfoService;
	private final BladeRedis bladeRedis;

	@GetMapping("/userApp-detailById")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "获取用户信息", notes = "传入用户ID")
	public R<UserAppVO> userDetailById(@ApiParam(value = "用户ID", required = true) @RequestParam Long id) {
		return R.data(apiService.getUserAppVo(id));
	}

	@PostMapping("/user-updateById")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "修改用户资料", notes = "传入用户ID")
	public R userUpdateById(@Valid @RequestBody UserAppUpdateRequest request) {
		User user = new User();
		user.setId(request.getUserId());
		user.setName(request.getName());
		user.setAvatar(request.getAvatar());
		user.setSex(request.getSex());
		user.setBirthday(request.getBirthday());
		boolean flg = userService.updateById(user);
		if (flg){
			//清除缓存
			bladeRedis.del(String.valueOf(request.getUserId()));
			CacheUtil.clear(USER_CACHE);
			return R.success("操作成功");
		}
		return R.fail("操作失败");
	}

	@PostMapping("/userApp-updateByUserId")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "修改简介说明", notes = "传入用户ID")
	public R userAppUpdateByUserId(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
								   @ApiParam(value = "简介说明", required = true) @RequestParam String userExplain) {
		UserApp userApp = new UserApp();
		userApp.setUserExplain(userExplain);
		boolean flg = userApp.update(Wrappers.<UserApp>lambdaQuery().eq(UserApp::getUserId,userId));
		if (flg){
			//清除缓存
			bladeRedis.del(String.valueOf(userId));
			return R.success("操作成功");
		}
		return R.fail("操作失败");
	}

	@GetMapping("/userAddress-page")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "查询用户地址数据", notes = "传入用户ID")
	public R<List<UserAddress>> userAddressPage(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId, Query query) {
		UserAddress userAddress = new UserAddress();
		userAddress.setUserId(userId);
		IPage<UserAddress> list = userAddressService.page(Condition.getPage(query), Condition.getQueryWrapper(userAddress));
		return R.data(list.getRecords());
	}

	@GetMapping("/userAddress-detailById")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "查询用户地址详情", notes = "传入地址ID, 0获取地址详情（传入地址ID）,1默认地址状态（用户ID）, 2获取地址详情并返回运费（传入地址ID）")
	public R<UserAddressVO> userAddressDetailById(@ApiParam(value = "地址ID/用户ID", required = true) @RequestParam Long id,
												  @ApiParam(value = "类型,默认为0", required = true) @RequestParam Integer type) {
		UserAddress userAddress = new UserAddress();
		if (type == 1){
			userAddress.setUserId(id);
			userAddress.setDefaultState(2);//默认标识
			UserAddress query = userAddressService.getOne(Condition.getQueryWrapper(userAddress));
			if(query == null){
				return R.fail("该地址不存在");
			}
			UserAddressVO vo = UserAddressWrapper.build().entityVO(query);
			vo.setWlPrice(0D);
			return R.data(vo);
		}else if (type == 2){
			UserAddress query = userAddressService.getById(id);
			if(query == null){
				return R.fail("该地址不存在");
			}
			UserAddressVO vo = UserAddressWrapper.build().entityVO(query);
			Region region = regionService.getById(vo.getDistrictCode());
			vo.setWlPrice(0D);
			if (region != null){
				Freight freight = freightService.getOne(Wrappers.<Freight>lambdaQuery().eq(Freight::getCode, region.getProvinceCode()));
				if (freight != null){
					vo.setWlPrice(freight.getFreight());
				}
			}
			return R.data(vo);
		}else{
			UserAddress query = userAddressService.getById(id);
			if(query == null){
				return R.fail("该地址不存在");
			}
			UserAddressVO vo = UserAddressWrapper.build().entityVO(query);
			vo.setWlPrice(0D);
			return R.data(vo);
		}
	}

	@GetMapping("/userAddress-detailByUserId")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "查询用户默认地址", notes = "传入用户ID")
	public R<UserAddress> userAddressDetailByUserId(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId) {
		UserAddress userAddress = new UserAddress();
		userAddress.setUserId(userId);
		userAddress.setDefaultState(2);//默认标识
		return R.data(userAddressService.getOne(Condition.getQueryWrapper(userAddress)));
	}

	@PostMapping("/userAddress-remove")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "删除用户地址", notes = "传入ids,可以批量删除，格式xx,xxx,xx")
	public R userAddressRemove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {

		return R.status(userAddressService.removeByIds(Func.toLongList(ids)));
	}

	@PostMapping("/userAddress-save")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "添加用户地址", notes = "添加用户地址")
	public R userAddressSave(@Valid @RequestBody AddressSaveRequest request) {
		if(StringUtil.isNotBlank(request.getPhone()) && !PhoneUtil.isMobile(request.getPhone())){
			return R.fail("请输入正确的手机号");
		}
		if(StringUtil.isEmpty(request.getUserId())){
			return R.fail("请求参数错误！");
		}
		UserAddress userAddress = Objects.requireNonNull(BeanUtil.copy(request, UserAddress.class));
		if (StringUtil.isEmpty(request.getDefaultState())){
			userAddress.setDefaultState(1);
		}
		if (StringUtil.isEmpty(request.getDetail())){
			return R.fail("请输入详细地址！");
		}
		userAddress.setCreateTime(DateUtil.now());
		//设置默认地址
		if (userAddress.getDefaultState() == 2){
			//用户所有的改为不默认
			UserAddress param = new UserAddress();
			param.setUserId(request.getUserId());
			UserAddress entity= new UserAddress();
			entity.setDefaultState(1);
			userAddressService.update(entity, Condition.getQueryWrapper(param));
			//清除缓存
			bladeRedis.del(String.valueOf(request.getUserId()));
		}
		return R.status(userAddressService.save(userAddress));
	}

	@PostMapping("/userAddress-update")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "修改用户收货地址", notes = "修改用户地址")
	public R userAddressUpdate(@Valid @RequestBody AddressUpdateRequest request) {
		/*if(StringUtil.isNotBlank(request.getPhone()) && !PhoneUtil.isMobile(request.getPhone())){
			return R.fail("请输入正确的手机号");
		}*/
		UserAddress userAddress = Objects.requireNonNull(BeanUtil.copy(request, UserAddress.class));
		userAddress.setUpdateTime(DateUtil.now());
		if (userAddress.getDefaultState() == 2){
			UserAddress entity= new UserAddress();
			entity.setDefaultState(1);
			UserAddress param = new UserAddress();
			param.setUserId(request.getUserId());
			userAddressService.update(entity, Condition.getQueryWrapper(param));
		}
		return R.status(userAddressService.updateById(userAddress));
	}

	@GetMapping("/userFeedbacks-page")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "查询反馈意见数据", notes = "传入用户ID")
	public R<List<UserFeedbacks>> userFeedbacksPage(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId, Query query) {
		UserFeedbacks userFeedbacks = new UserFeedbacks();
		userFeedbacks.setUserId(userId);
		IPage<UserFeedbacks> list = userFeedbacksService.page(Condition.getPage(query),
			Condition.getQueryWrapper(userFeedbacks).lambda().orderByAsc(UserFeedbacks::getCreateTime));
		return R.data(list.getRecords());
	}

	@GetMapping("/userFeedbacks-detailById")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "反馈意见详情", notes = "传入意见ID")
	public R<UserFeedbacks> userFeedbacksDetailById(@ApiParam(value = "意见ID", required = true) @RequestParam String id) {
		return R.data(userFeedbacksService.getById(id));
	}

	@PostMapping("/userFeedbacks-save")
	@ApiOperationSupport(order = 11)
	@ApiOperation(value = "添加反馈意见", notes = "添加反馈意见")
	public R userFeedbacksSave(@Valid @RequestBody UserFeedbacksSaveRequest request) {
		UserFeedbacks userFeedbacks = Objects.requireNonNull(BeanUtil.copy(request, UserFeedbacks.class));
		userFeedbacks.setCreateTime(DateUtil.now());
		return R.status(userFeedbacksService.save(userFeedbacks));
	}

	@GetMapping("/userRecom-page")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "查询用户团队成员和直推记录数据", notes = "传入用户ID，查询的数据")
	public R<List<UserRecomVO>> userRecomPage(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
											  @ApiParam(value = "类型:1团队成员（默认）、2直推记录", required = true) @RequestParam Integer type, Query query) {
		if (type == 2){
			IPage<UserRecomVO> list = userRecomService.selectUserRecomVoPage(Condition.getPage(query), userId,null);
			return R.data(list.getRecords());
		}
		IPage<UserRecomVO> list = userRecomService.selectUserRecomVoPage(Condition.getPage(query), userId, userId);
		return R.data(list.getRecords());
	}

	@GetMapping("/user-teamAndRecomById")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "查询用户团队人数和直荐人员数据", notes = "传入用户ID")
	public R<TeamResponse> teamAndRecomByUserId(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId) {
		TeamResponse response = new TeamResponse();
		UserApp userApp = new UserApp();
		//团队不包含直推人数
		Integer teamNum = userApp.selectCount(Condition.getQueryWrapper(userApp).lambda()
			.like(UserApp::getParentPath, userId).ne(UserApp::getParentId, userId));
		userApp.setParentId(userId);
		Integer recomNum = userApp.selectCount(Condition.getQueryWrapper(userApp).lambda()
			.eq(UserApp::getParentId, userId));
		response.setTeamNum(teamNum);
		response.setRecomNum(recomNum);
		return R.data(response);
	}

	@GetMapping("/userBankCards-page")
	@ApiOperationSupport(order = 14)
	@ApiOperation(value = "查询用户银行卡数据", notes = "传入用户ID")
	public R<List<UserBankCardsVO>> userBankCardsPage(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId, Query query) {
		UserBankCards userBankCards = new UserBankCards();
		userBankCards.setUserId(userId);
		IPage<UserBankCards> list = userBankCardsService.page(Condition.getPage(query),
			Condition.getQueryWrapper(userBankCards).lambda().orderByAsc(UserBankCards::getSort));
		return R.data(UserBankCardsWrapper.build().listVO(list.getRecords()));
	}

	@PostMapping("/userBankCards-save")
	@ApiOperationSupport(order = 15)
	@ApiOperation(value = "绑定银行卡", notes = "绑定银行卡")
	public R userBankCardsSave(@Valid @RequestBody UserBankCardsSaveRequest request) {
		UserBankCards userBankCards = Objects.requireNonNull(BeanUtil.copy(request, UserBankCards.class));
		userBankCards.setCreateTime(DateUtil.now());
		userBankCards.setUpdateTime(DateUtil.now());
		userBankCards.setSort(100);
		return R.status(userBankCardsService.save(userBankCards));
	}

	@PostMapping("/userBankCards-update")
	@ApiOperationSupport(order = 16)
	@ApiOperation(value = "修改银行卡", notes = "传入主键ID")
	public R userBankCardsUpdate(@Valid @RequestBody UserBankCardsUpdateRequest request) {
		UserBankCards userBankCards = Objects.requireNonNull(BeanUtil.copy(request, UserBankCards.class));
		userBankCards.setUpdateTime(DateUtil.now());
		return R.status(userBankCardsService.updateById(userBankCards));
	}

	@GetMapping("/userBankCards-detailById")
	@ApiOperationSupport(order = 17)
	@ApiOperation(value = "银行卡详情", notes = "传入主键ID")
	public R<UserBankCardsVO> userBankCardsDetailById(@ApiParam(value = "用户银行卡主键ID", required = true) @RequestParam String id) {
		UserBankCards userBankCards = userBankCardsService.getById(id);
		return R.data(UserBankCardsWrapper.build().entityVO(userBankCards));
	}

	@GetMapping("/userTicket-page")
	@ApiOperationSupport(order = 18)
	@ApiOperation(value = "查询酒票明细数据", notes = "传入用户ID")
	public R<List<UserTicketVO>> userTicketPage(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId, Query query) {
		UserTicket userTicket = new UserTicket();
		userTicket.setUserId(userId);
		IPage<UserTicket> list = userTicketService.page(Condition.getPage(query),
			Condition.getQueryWrapper(userTicket).lambda()
				.orderByDesc(UserTicket::getCreateTime));
		return R.data(UserTicketWrapper.build().listVO(list.getRecords()));
	}

	@GetMapping("/userTicket-transferPage")
	@ApiOperationSupport(order = 20)
	@ApiOperation(value = "查询酒票转让人员选择数据", notes = "传入用户ID")
	public R<List<UserVO>> userTicketTransferPage(@ApiParam(value = "账号/姓名/手机号/推荐码", required = true) @RequestParam(required = false) String name, Query query) {
		User user = new User();
		user.setUserType(2);//app用户
		if (StringUtil.isNotBlank(name)){
			IPage<User> list = userService.page(Condition.getPage(query),
				Condition.getQueryWrapper(user).lambda()
					.like(User::getAccount, name).or()
					.like(User::getName, name).or()
					.like(User::getPhone, name).or()
					.like(User::getCode, name));
			return R.data(UserWrapper.build().listVO(list.getRecords()));
		}else{
			IPage<User> list = userService.page(Condition.getPage(query),
				Condition.getQueryWrapper(user).lambda().exists("select 1 from t_user_ticket t where t.user_id = id"));
			return R.data(UserWrapper.build().listVO(list.getRecords()));
		}
	}

	@PostMapping("/userTicket-transfer")
	@ApiOperationSupport(order = 21)
	@ApiOperation(value = "酒票转让", notes = "传入用户ID")
	public R userTicketTransfer(@Valid @RequestBody UserTicketTransferRequest request) {
		//清除缓存
		bladeRedis.del(String.valueOf(request.getUserId()));
		return R.status(userService.tickerTransfer(request.getUserId(),request.getTransferId(), request.getTicket()));
	}

	@GetMapping("/versionUpgrade")
	@ApiOperationSupport(order = 22)
	@ApiOperation(value = "获取最新版本", notes = "获取最新版本")
	public R<VersionUpgrade> versionUpgrade() {
		VersionUpgrade versionUpgrade = versionUpgradeService.getOne(Wrappers.<VersionUpgrade>lambdaQuery()
			.eq(VersionUpgrade::getStatus ,2).orderByDesc(VersionUpgrade::getVersionCode).orderByDesc(VersionUpgrade::getSort),false);
		return R.data(versionUpgrade);
	}

	@GetMapping("/detail")
	@ApiOperationSupport(order = 22)
	@ApiOperation(value = "查询用户实名认证", notes = "传入userCardInfo")
	public R<UserCardInfo> detail(UserCardInfo userCardInfo) {
		UserCardInfo detail = userCardInfoService.getOne(Condition.getQueryWrapper(userCardInfo));
		return R.data(detail);
	}

	@PostMapping("/userCardInfo-save")
	@ApiOperationSupport(order = 23)
	@ApiOperation(value = "用户实名认证", notes = "传入用户ID")
	public R userCardInfo(@Valid @RequestBody UserCardInfoSaveRequest request) {
		User user = userService.getById(request.getUserId());
		if (user == null){
			return R.fail("该用户不存在！");
		}
		UserCardInfo userCardInfo = Objects.requireNonNull(BeanUtil.copy(request, UserCardInfo.class));
		userCardInfo.setIsAuth(2);
		boolean flg = userCardInfoService.saveOrUpdate(userCardInfo,Wrappers.<UserCardInfo>lambdaQuery()
			.eq(UserCardInfo::getUserId, request.getUserId()));
		if (flg){
			User param = new User();
			param.setId(user.getId());
			param.setRealName(request.getTrueName());
			userService.updateById(param);
		}
		//清除缓存
		bladeRedis.del(String.valueOf(request.getUserId()));
		return R.status(flg);
	}

}
