
package com.tmerclub.cloud.distribution.controller.app;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.order.vo.UserShoppingDataVO;
import com.tmerclub.cloud.api.payment.allinpay.member.resp.BindCard;
import com.tmerclub.cloud.api.payment.allinpay.member.resp.PersonalMemberInfo;
import com.tmerclub.cloud.api.payment.feign.AllinpayFeignClient;
import com.tmerclub.cloud.api.platform.feign.ConfigFeignClient;
import com.tmerclub.cloud.api.platform.vo.DistributionConfigApiVO;
import com.tmerclub.cloud.api.user.feign.UserFeignClient;
import com.tmerclub.cloud.api.user.vo.UserApiVO;
import com.tmerclub.cloud.common.bean.PaySettlementConfig;
import com.tmerclub.cloud.common.constant.AutoCheckEnum;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.Json;
import com.tmerclub.cloud.common.util.PriceUtil;
import com.tmerclub.cloud.distribution.constant.DistributionUserStateEnum;
import com.tmerclub.cloud.distribution.dto.DistributionUserRegisterDTO;
import com.tmerclub.cloud.distribution.model.DistributionUser;
import com.tmerclub.cloud.distribution.service.DistributionConfigService;
import com.tmerclub.cloud.distribution.service.DistributionUserService;
import com.tmerclub.cloud.distribution.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 分销员注册接口
 *
 * @author cl
 * @date 2021-08-16 10:00:21
 */
@RestController("appDistributionRegisterController")
@RequestMapping("/distributionRegister")
@Tag(name = "分销员绑定关系")
public class DistributionRegisterController {

    private static final Logger logger = LoggerFactory.getLogger(DistributionRegisterController.class);

    @Autowired
    private DistributionConfigService distributionConfigService;
    @Autowired
    private DistributionUserService distributionUserService;
    @DubboReference
    private UserFeignClient userFeignClient;
    @DubboReference
    private OrderFeignClient orderFeignClient;
    @DubboReference
    private ConfigFeignClient configFeignClient;
    @DubboReference
    private AllinpayFeignClient allinpayFeignClient;

    /**
     * 成为分销员
     */
    @PostMapping("/addDistributionUser")
    @Operation(summary = "申请成为分销员", description = "申请成为分销员，返回分销员状态 0 待审核 1 正常")
    public ServerResponseEntity<Integer> addDistributionUser(@Valid @RequestBody DistributionUserRegisterDTO distributionUserRegisterDTO) {
        Long userId = AuthUserContext.get().getUserId();
        // 查询用户信息，补充分销员手机号
        ServerResponseEntity<UserApiVO> userResponse = userFeignClient.getUserData(userId);
        if (!userResponse.isSuccess()) {
            throw new LuckException(userResponse.getMsg());
        }
        UserApiVO user = userResponse.getData();
        if (Objects.isNull(user)) {
            throw new LuckException("用户不存在");
        }
        if (Objects.isNull(user.getPhone())) {
            throw new LuckException("用户手机号未绑定");
        }
        distributionUserRegisterDTO.setUserMobile(user.getPhone());
        logger.debug(Json.toJsonString(distributionUserRegisterDTO));
        // 店铺分销员审核设置
        DistributionConfigApiVO distributionConfig = distributionConfigService.getDistributionConfig();
        // 判断传入的资料是否齐全
        if (distributionConfig == null || Objects.isNull(distributionConfig.getAutoCheck())) {
            // 分销设置异常
            throw new LuckException("分销设置异常");
        }
        if (distributionConfig.getIdentityCardNumber()) {
            if (!StrUtil.isNotBlank(distributionUserRegisterDTO.getIdentityCardNumber())) {
                // 申请填写信息不全,需要身份证号
                throw new LuckException("申请填写信息不全,需要身份证号");
            }
        }
        if (distributionConfig.getIdentityCardPic()) {
            if (!StrUtil.isNotBlank(distributionUserRegisterDTO.getIdentityCardPicBack()) || !StrUtil.isNotBlank(distributionUserRegisterDTO.getIdentityCardPicFront()) || !StrUtil.isNotBlank(distributionUserRegisterDTO.getIdentityCardPicHold())) {
                // 申请填写信息不全,需要身份证照片
                throw new LuckException("申请填写信息不全,需要身份证照片");
            }
        }
        if (distributionConfig.getRealName()) {
            if (!StrUtil.isNotBlank(distributionUserRegisterDTO.getRealName())) {
                // 申请填写信息不全,需要真实姓名
                throw new LuckException("申请填写信息不全,需要真实姓名");
            }
        }
        // 检查通联信息
        this.distributionAllinpayCheck();

        DistributionUserVO distributionUserVO = distributionUserService.getByUserId(userId);
        // 检查分销员信息
        checkUserInfo(distributionUserRegisterDTO, distributionUserVO);

        DistributionUser distributionUser = new DistributionUser();
        distributionUser.setUserId(userId);

        // 设置分享人信息
        setSharer(distributionUserRegisterDTO, userId, distributionUser);

        if (distributionConfig.getAutoCheck() == 1) {
            autoCheck(distributionConfig, userId, distributionUser);
        } else if(Objects.equals(distributionConfig.getAutoCheck(), AutoCheckEnum.NO_AUDIT.value())){
            // 不需要审核
            distributionUser.setState(1);
            distributionUser.setBindTime(new Date());
        } else {
            // 待审核
            distributionUser.setState(DistributionUserStateEnum.WAIT_AUDIT.value());
        }

        //设置信息
        distributionUser.setUserMobile(distributionUserRegisterDTO.getUserMobile());
        distributionUser.setRealName(distributionUserRegisterDTO.getRealName());
        distributionUser.setIdentityCardNumber(distributionUserRegisterDTO.getIdentityCardNumber());
        distributionUser.setIdentityCardPicFront(distributionUserRegisterDTO.getIdentityCardPicFront());
        distributionUser.setIdentityCardPicHold(distributionUserRegisterDTO.getIdentityCardPicHold());
        distributionUser.setIdentityCardPicBack(distributionUserRegisterDTO.getIdentityCardPicBack());

        //设置用户信息字段
        distributionUser.setNickName(user.getNickName());
        distributionUser.setPic(user.getPic());

        distributionUserService.registerDistributionUser(distributionUser);

        // 清除缓存
        distributionUserService.removeCacheByUserId(distributionUser.getUserId());
        return ServerResponseEntity.success(distributionUser.getState());
    }

    @GetMapping("/checkAllinpayInfo")
    @Operation(summary = "检查分销条件(通联)")
    public ServerResponseEntity<Void> checkAllinpayInfo() {
        // 检查通联信息
        this.distributionAllinpayCheck();
        return ServerResponseEntity.success();
    }

    private void setSharer(DistributionUserRegisterDTO distributionUserRegisterDTO, Long userId, DistributionUser distributionUser) {
        String sharerDistributionUserId = distributionUserRegisterDTO.getSharer();
        if (StrUtil.isNotBlank(sharerDistributionUserId)) {
            DistributionUser parentUser = distributionUserService.getByDistributionUserId(Long.parseLong(sharerDistributionUserId));
            if (parentUser == null) {
                // 无法获取邀请人信息
                throw new LuckException("无法获取邀请人信息");
            }
            if (Objects.equals(parentUser.getUserId(), userId)) {
                // 自己无法邀请自己
                throw new LuckException("自己无法邀请自己");
            }
            if (!Objects.equals(parentUser.getState(), DistributionUserStateEnum.PER_BAN.value())
                    && !Objects.equals(parentUser.getState(), DistributionUserStateEnum.BAN.value())) {
                //上级不能是暂时封禁或永久封禁状态
                //设置上级id
                distributionUser.setParentId(parentUser.getDistributionUserId());
                //设置上级ids
                if (parentUser.getParentId() == null) {
                    distributionUser.setParentIds(StringUtils.join(StrUtil.COMMA, parentUser.getDistributionUserId(), StrUtil.COMMA));
                } else {
                    distributionUser.setParentIds(StringUtils.join(parentUser.getParentIds(), parentUser.getDistributionUserId(), StrUtil.COMMA));
                }

                distributionUser.setGrade(parentUser.getGrade() + 1);
            } else {
                throw new LuckException("当前邀请人已被封禁");
            }
        } else {
            distributionUser.setGrade(0);
        }
    }

    private void checkUserInfo(DistributionUserRegisterDTO distributionUserRegisterDTO, DistributionUserVO distributionUser) {
        if (distributionUser != null) {
            if (Objects.equals(distributionUser.getState(), DistributionUserStateEnum.WAIT_AUDIT.value())) {
                // 你已经提交过审核了,请耐心等待
                throw new LuckException("你已经提交过审核了,请耐心等待");
            } else if (Objects.equals(distributionUser.getState(), DistributionUserStateEnum.PER_BAN.value())) {
                // 该账户已被永久封禁
                throw new LuckException("该账户已被永久封禁");
            } else if (Objects.equals(distributionUser.getState(), DistributionUserStateEnum.BAN.value())) {
                // 已暂时封禁不可申请,请联系管理员
                throw new LuckException("已暂时封禁不可申请,请联系管理员");
            } else if (Objects.equals(distributionUser.getState(), DistributionUserStateEnum.NORMAL.value())) {
                // 你的审核已经通过,无需再次审核
                throw new LuckException("你的审核已经通过,无需再次审核");
            }
        }
        List<DistributionUser> distributionUsersDb = distributionUserService.getDistributionUserByIdCardNumberAndUserMobile(distributionUserRegisterDTO.getIdentityCardNumber(), distributionUserRegisterDTO.getUserMobile());
        for (DistributionUser distributionUserDb : distributionUsersDb) {
            if (StrUtil.isNotBlank(distributionUserRegisterDTO.getIdentityCardNumber()) && StrUtil.equals(distributionUserDb.getIdentityCardNumber(), distributionUserRegisterDTO.getIdentityCardNumber())) {
                // 该身份证号码已存在
                throw new LuckException("该身份证号码已在系统存在");
            } else if (Objects.equals(distributionUserDb.getUserMobile(), distributionUserRegisterDTO.getUserMobile())) {
                // 该手机号码已存在
                throw new LuckException("该手机号码已在系统存在");
            }
        }
    }

    private void autoCheck(DistributionConfigApiVO distributionConfig, Long userId, DistributionUser distributionUser) {
        //判断是否需要购买置指定商品
        if (CollUtil.isNotEmpty(distributionConfig.getSpuIdList())) {
            boolean has = false;
            Long distributionUserUserId = distributionUser.getUserId();
            for (Long spu : distributionConfig.getSpuIdList()) {
                // 判断有没有没有购买过指定商品
                ServerResponseEntity<Long> orderResponse = orderFeignClient.hasBuySuccessProd(spu, distributionUserUserId);
                if (!orderResponse.isSuccess()) {
                    throw new LuckException(orderResponse.getMsg());
                }
                if (orderResponse.getData() > 0L) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                // 不符合申请条件，请联系客服进行申请
                throw new LuckException("不符合申请条件，请联系客服进行申请");
            }
        }
        // 获取用户金额统计数据
        ServerResponseEntity<UserShoppingDataVO> userShoppingDataResponse = orderFeignClient.calculateUserInShopData(userId);
        if (!userShoppingDataResponse.isSuccess()) {
            // 消费金额不符合要求
            throw new LuckException("消费金额不符合要求");
        }
        UserShoppingDataVO userShoppingData = userShoppingDataResponse.getData();

        //判断是否需要消费金额条件
        if (distributionConfig.getExpenseAmount() != null) {
            if (userShoppingData.getSumOfConsumption() == null) {
                userShoppingData.setSumOfConsumption(0L);
            }
            // 转换成元
            BigDecimal sumOfConsumption = PriceUtil.toDecimalPrice(userShoppingData.getSumOfConsumption());
            if (sumOfConsumption.compareTo(distributionConfig.getExpenseAmount()) < 0) {
                // 消费金额不符合要求
                throw new LuckException("消费金额不符合要求");
            }
        }
        //判断是否需要达到消费笔数条件
        if (distributionConfig.getExpenseNumber() != null) {
            if (userShoppingData.getExpenseNumber() < distributionConfig.getExpenseNumber()) {
                // 消费笔数不符合要求
                throw new LuckException("消费笔数不符合要求");
            }
        }
        distributionUser.setState(DistributionUserStateEnum.NORMAL.value());
        distributionUser.setBindTime(new Date());
    }

    /**
     * 分销员通联信息检查
     */
    private void distributionAllinpayCheck() {
        // 是否开启通联支付（若开启需检查通联平台的账号信息）
        String data = configFeignClient.getConfig(Constant.PAY_SETTLEMENT_CONFIG).getData();
        if (!ObjectUtils.isEmpty(data)) {
            PaySettlementConfig config = JSON.parseObject(data, PaySettlementConfig.class);
            if (config.getPaySettlementType() != null && config.getPaySettlementType() == 1) {
                // 查询通联平台会员信息
                String bizUserId = String.valueOf(AuthUserContext.get().getUserId());
                ServerResponseEntity<PersonalMemberInfo> resp = allinpayFeignClient.getPersonalMemberInfo(bizUserId);
                if (!resp.isSuccess() || ObjectUtils.isEmpty(resp.getData())) {
                    throw new LuckException("通联会员未开通or通联服务异常，请联系管理员进行处理");
                }
                PersonalMemberInfo personalMemberInfo = resp.getData();
                // 检查是否实名认证
                if (personalMemberInfo.getIdentityChecked() == null
                        || !personalMemberInfo.getIdentityChecked()) {
                    throw new LuckException("通联未实名认证");
                }
                // 检查是否绑定手机号
                if (personalMemberInfo.getPhoneChecked() == null
                        || !personalMemberInfo.getPhoneChecked()) {
                    throw new LuckException("通联未绑定手机号");
                }
                // 检查是否绑定银行卡
                ServerResponseEntity<List<BindCard>> bankCardResp = allinpayFeignClient.listBindCard(bizUserId, null);
                if (!bankCardResp.isSuccess() || CollectionUtils.isEmpty(bankCardResp.getData())) {
                    throw new LuckException("通联未绑定银行卡");
                }
            }
        }
    }
}
