package org.springblade.modules.api.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.protostuff.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import oracle.jdbc.proxy.annotation.Post;
import org.springblade.common.base.BaseEntity;
import org.springblade.common.cache.DictBizCache;
import org.springblade.common.cache.DictCache;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.enums.DictBizEnum;
import org.springblade.common.enums.DictEnum;
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.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
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.service.IApiService;
import org.springblade.modules.desk.entity.Notice;
import org.springblade.modules.desk.service.INoticeService;
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.wrapper.UserAddressWrapper;
import org.springblade.modules.platform.wrapper.UserBankCardsWrapper;
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.service.impl.UserServiceImpl;
import org.springblade.modules.system.vo.UserAppVO;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 UserCenterController extends BladeController {

	private final IUserAddressService userAddressService;
	private final IUserFeedbacksService userFeedbacksService;
	private final IUserService userService;
	private final IUserBankCardsService userBankCardsService;
	private final IVersionUpgradeService versionUpgradeService;
	private final IApiService apiService;
	private final IRegionService regionService;
	private final IFreightService freightService;
	private final IUserCardInfoService userCardInfoService;
	private final BladeRedis bladeRedis;
	@Resource
	private IMessageService messageService;
	@Resource
	private UserAppService userAppService;
	@Resource
	private INoticeService noticeService;

	@GetMapping("/userInfo/get")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "获取用户信息")
	public R<UserAppVO> userDetailById() {
		User user1 = userService.getById(AuthUtil.getUserId());
		Assert.notNull(user1, "未查询到用户信息，请重启小程序后再试");
		UserApp query = userAppService.getBaseMapper().selectOne(Wrappers.<UserApp>lambdaQuery().eq(UserApp::getUserId, getUser().getUserId()));
		if (query == null) {
			return null;
		}
		UserAppVO vo = BeanUtil.copy(query, UserAppVO.class);
		User user = userService.getById(vo.getUserId());
		vo.setAvatar(user.getAvatar());
		vo.setRealName(user.getRealName());
		vo.setName(user.getName());
		vo.setSexDisplayName(DictCache.getValue(DictEnum.SEX, user.getSex()));
		vo.setStateDisplayName(DictBizCache.getValue(DictBizEnum.USER_STATE, query.getState()));
		vo.setUsername(user.getAccount());
		vo.setPhone(user.getPhone());
		vo.setBirthday(user.getBirthday());
		vo.setWxQrcode(user.getWxQrcode());
		return R.data(vo);
	}

	@PostMapping("/userInfo/save")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "修改用户资料", notes = "传入用户ID")
	public R userUpdateById(@Valid @RequestBody UserAppUpdateRequest request) {
		User user = userService.getById(getUser().getUserId());
		user.setName(request.getName());
		user.setAvatar(request.getAvatar());
		user.setSex(request.getSex());
		user.setPhone(request.getPhone());
		user.setWxQrcode(request.getWxQrcode());
		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());
	}

	@PostMapping("/address/list")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "查询用户地址数据")
	public R<List<UserAddress>> userAddressList(@RequestBody Query query) {
		LambdaQueryWrapper<UserAddress> q = new LambdaQueryWrapper<>();
		q.eq(UserAddress::getUserId,getUser().getUserId());
		q.orderByDesc(UserAddress::getDefaultState);
		IPage<UserAddress> list = userAddressService.page(Condition.getPage(query), q);
		return R.data(list.getRecords());
	}

	@GetMapping("/address/defaultSet")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "设置默认地址")
	public R defaultSet(@RequestParam(name = "id") Long id) {
		UserAddress userAddress = userAddressService.getById(id);
		LambdaUpdateWrapper<UserAddress> u=new LambdaUpdateWrapper<>();
		u.set(UserAddress::getDefaultState,1);
		u.eq(UserAddress::getUserId,getUser().getUserId());
		userAddressService.update(u);

		userAddress.setDefaultState(2);
		userAddressService.updateById(userAddress);
		return R.success("操作成功");
	}

	@GetMapping("/address/removeById")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "删除地址")
	public R removeById(@RequestParam(name = "id") Long id) {
		userAddressService.removeById(id);
		return R.success("操作成功");
	}

	@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));
	}

	@PostMapping("/getMyDetail")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "查询个人数据")
	public R getMyDetail(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId){
		UserApp userApp = new UserApp();
		UserApp app = userApp.selectOne(Condition.getQueryWrapper(userApp).lambda().eq(UserApp::getUserId, userId));
		User user = userService.getById(userId);
		Map<Object, Object> map = new HashMap<>();
		map.put("nowMoney", app.getNowMoney());//余额
		map.put("redMoney", app.getRedMoney());//红包余额
		map.put("ticket", app.getTicket());//绿色积分
		map.put("account", user.getAccount());//账号
		return R.data(map);
	}

	@PostMapping("/getUserByAccount")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "通过电话查询个人数据")
	public R getUserByAccount(@ApiParam(value = "用户电话", required = true) @RequestParam Long account){
		User user = userService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getAccount, account));
		if(ObjectUtil.isNull(user)){
			return R.fail("用户电话不正确，查询不到用户请核实");
		}
		UserApp userApp = new UserApp();
		UserApp app = userApp.selectOne(Condition.getQueryWrapper(userApp).lambda().eq(UserApp::getUserId, user.getId()));
		User parentUser = userService.getById(app.getParentId());
		Map<Object, Object> map = new HashMap<>();
		map.put("nowMoney", app.getNowMoney());//余额
		map.put("redMoney", app.getRedMoney());//余额
		map.put("ticket", app.getTicket());//绿色积分
		map.put("integral", app.getIntegral());//红色积分
		map.put("userId", user.getId());//用户id
		map.put("userName", user.getRealName());//用户id
		map.put("account", account);//用户电话
		map.put("parentUserName", parentUser.getRealName());//推荐人名称
		map.put("parentUserAccount", parentUser.getAccount());//推荐人电话

		String roleName = "";
		if(app.getIsRole() == 1){
			roleName = "城市合伙人";
		}else if(app.getIsRole() == 2){
			roleName = "创客";
		}else {
			roleName = "城市合伙人,创客";
		}
		map.put("roleName", roleName);//用户角色名称
		return R.data(map);
	}




	@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-update")
	@ApiOperationSupport(order = 15)
	@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("/versionUpgrade")
	@ApiOperationSupport(order = 16)
	@ApiOperation(value = "获取最新版本", notes = "获取最新版本")
	public R<VersionUpgrade> versionUpgrade(@RequestParam(value = "userVersionName", required = false) String userVersionName) {
		if (StrUtil.isNotBlank(userVersionName)) {
			// 记录用户版本号
			Long userId = AuthUtil.getUserId();
			User user = userService.getById(userId);
			if (user != null && userVersionName.equals(user.getUserAppVersion())) {
				user.setUserAppVersion(userVersionName);
				userService.updateById(user);
			}
		}
		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 = 17)
	@ApiOperation(value = "查询用户实名认证", notes = "传入userCardInfo")
	public R<UserCardInfo> detail(UserCardInfo userCardInfo) {
		UserCardInfo detail = userCardInfoService.getOne(Condition.getQueryWrapper(userCardInfo));
		return R.data(detail);
	}

	@ApiOperation(value = "注销")
	@ApiOperationSupport(order = 19)
	@PostMapping("/logOut")
	public R logOut(){
		User user = userService.getById(AuthUtil.getUserId());
		if(ObjectUtil.isNotNull(user.getLogOut()) && user.getLogOut() == 1){
			return R.fail("用户已注销，无法重复注销");
		}
		user.setLogOut(1);
		return R.status(userService.updateUser(user));
	}


	@ApiOperation("获取个人消息")
	@ApiOperationSupport(order = 20)
	@PostMapping("getMyMessage")
	public R<List<Message>> getMyMessage(@RequestBody Query query){
		IPage<Message> pages = messageService.page(Condition.getPage(query), Wrappers.lambdaQuery(Message.class).eq(Message::getUserId, AuthUtil.getUserId()).orderByDesc(BaseEntity::getCreateTime));
		return R.data(pages.getRecords());
	}


	@ApiOperation("获取系统公告")
	@ApiOperationSupport(order = 21)
	@PostMapping("getNotice")
	public R<List<Notice>> getNotice(@RequestBody Query query){
		IPage<Notice> page = noticeService.page(Condition.getPage(query), Wrappers.lambdaQuery(Notice.class)
				.eq(Notice::getCategory, 1).eq(org.springblade.core.mp.base.BaseEntity::getStatus, 1));

		return R.data(page.getRecords());
	}


	@ApiOperation("用户协议")
	@ApiOperationSupport(order = 21)
	@GetMapping("/getNoticeByType")
	public R<Notice> getNoticeByType(@RequestParam(name = "type") Integer type){
		LambdaQueryWrapper<Notice> q = new LambdaQueryWrapper<>();
		q.eq(Notice::getCategory,type);
		q.orderByDesc(Notice::getCreateTime);
		q.last("limit 1");
		Notice notice = noticeService.getOne(q);
		return R.data(notice);
	}
}
