package com.hzs.member.self.controller.api;

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.constant.msg.ConfigMsgConstants;
import com.hzs.common.core.constant.msg.FinanceMsgConstants;
import com.hzs.common.core.enums.EApprovalBusiness;
import com.hzs.common.core.enums.ESmsTemplate;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.member.self.CuSelfServiceLog;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import com.hzs.member.account.dto.BusinessCommissionDTO;
import com.hzs.member.account.dto.MemberAmountDTO;
import com.hzs.member.account.dto.MemberBalanceDTO;
import com.hzs.member.account.service.ICuMemberAuthenticationService;
import com.hzs.member.account.service.ICuMemberTradeService;
import com.hzs.member.account.vo.CuMemberAuthenticationVO;
import com.hzs.member.base.service.ICuMemberService;
import com.hzs.member.self.service.ICuSelfServiceLogService;
import com.hzs.member.self.vo.DomicileChangeVO;
import com.hzs.member.sms.service.impl.ApiSmsServiceImpl;
import com.hzs.system.config.IServiceChargeServiceApi;
import com.hzs.system.config.dto.ServiceChargeDTO;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.ApprovalInfoDTO;
import com.hzs.system.sys.dto.ApprovalItemInfoDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 变理户籍
 *
 * @Description:
 * @Author: ljc
 * @Time: 2023/4/18 10:07
 * @Classname: ApiDomicileChangeController
 * @Package_name: com.hzs.member.self.controller.api
 */
@Slf4j
@RequestMapping("/api/change-domicile")
@RestController
public class ApiDomicileChangeController extends BaseController {

    @Autowired
    private ICuMemberAuthenticationService cuMemberAuthenticationService;

    @Autowired
    private ICuMemberService cuMemberService;

    @Autowired
    private ApiSmsServiceImpl apiSmsService;

    @Autowired
    private ICuMemberTradeService cuMemberTradeService;

    @Autowired
    private ICuSelfServiceLogService serviceLogService;

    @DubboReference
    IServiceChargeServiceApi serviceChargeServiceApi;

    @DubboReference
    IApprovalServiceApi iApprovalServiceApi;

    /**
     * 查询可申请信息
     *
     * @return AjaxResult
     */
    @GetMapping("/application-info-list")
    public AjaxResult applicationInformation() {
        Long pkMember = SecurityUtils.getUserId();
        CuMemberExt member = cuMemberService.getMemberById(pkMember);
        DomicileChangeVO domicileChangeVO = DomicileChangeVO.builder().memberCode(member.getMemberCode())
                .memberName(member.getMemberName()).phone(member.getPhone())
                .changeNum(MagicNumberConstants.CHANGE_NUM).build();
        return AjaxResult.success(domicileChangeVO);
    }


    @GetMapping("/application-info-detail")
    public AjaxResult applicationInformationDetail() {
        return AjaxResult.success(serviceLogService.selectDomicileChangeByPkMember(SecurityUtils.getUserId(), EApprovalBusiness.DOMICILE_CHANGE.getValue(), SecurityUtils.getPkCountry()));
    }

    /**
     * 查询已申请信息
     *
     * @return AjaxResult
     */
    @GetMapping("/applied-info-list")
    public AjaxResult appliedInformation() {
        DomicileChangeVO domicileChangeVO = DomicileChangeVO.builder().pkMember(SecurityUtils.getUserId())
                .pkCountry(SecurityUtils.getPkCountry()).editType(EApprovalBusiness.DOMICILE_CHANGE.getValue()).build();
        List<DomicileChangeVO> domicileChangeVOList = (List<DomicileChangeVO>) serviceLogService.selectSelfServiceByPkMember(domicileChangeVO)[1];
        return AjaxResult.success(domicileChangeVOList);
    }


    /**
     * 自助服务是否显示户籍认证
     *
     * @return AjaxResult
     */
    @GetMapping("/show-index-domicile")
    public AjaxResult showIndexDomicile() {
        return AjaxResult.success(serviceLogService.showIndexDomicile(SecurityUtils.getPkCountry(), SecurityUtils.getUserId()));
    }


    /**
     * 申请户籍变更
     *
     * @param domicileChangeVO 变更信息
     * @return TableDataInfo
     */
    @PostMapping("/change-domicile")
    @RepeatSubmitSimple
    public AjaxResult changeDomicile(@RequestBody DomicileChangeVO domicileChangeVO) {
        Long pkMember = SecurityUtils.getUserId();
        Integer pkCountry = SecurityUtils.getPkCountry();
        if (StringUtils.isEmpty(domicileChangeVO.getChangePhone())) {
            return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.MEMBER_PHONE_CANNOT_EMPTY));
        }
        if (StringUtils.isEmpty(domicileChangeVO.getChangeMemberName())) {
            return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.MEMBER_NAME_CANNOT_EMPTY));
        }
        if (StringUtils.isEmpty(domicileChangeVO.getIdFront())) {
            return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.ID_FRONT_CANNOT_EMPTY));
        }
        if (StringUtils.isEmpty(domicileChangeVO.getIdBack())) {
            return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.ID_BACK_CANNOT_EMPTY));
        }
        if (StringUtils.isEmpty(domicileChangeVO.getChangeIdFront())) {
            return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.ID_FRONT_CANNOT_EMPTY));
        }
        if (StringUtils.isEmpty(domicileChangeVO.getChangeIdBack())) {
            return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.ID_BACK_CANNOT_EMPTY));
        }
        domicileChangeVO.setPkCountry(pkCountry);
        domicileChangeVO.setPkMember(pkMember);
        //是否有正在审批业务
        AjaxResult existApprovalData = isExistApprovalData(domicileChangeVO);
        if (!existApprovalData.equals(AjaxResult.success())) {
            return existApprovalData;
        }
        //余额是否充足
        AjaxResult accountBalance = isAccountBalance(domicileChangeVO);
        if (!accountBalance.equals(AjaxResult.success())) {
            return accountBalance;
        }
        //验证码校验
        String key = ESmsTemplate.VERIFICATION.getCache() + pkMember;
        String message = apiSmsService.checkSms(key, domicileChangeVO.getVerificationCode());
        if (null != message) {
            return AjaxResult.error(message);
        }
        return toAjax(serviceLogService.saveChangeDomicile(domicileChangeVO));
    }


    /**
     * 显示户籍变更信息
     *
     * @return AjaxResult
     */
    @GetMapping("/show-change-domicile")
    public AjaxResult showChangeDomicile() {
        String idBack = null;
        String idFront = null;
        Long pkMember = SecurityUtils.getUserId();
        Integer pkCountry = SecurityUtils.getPkCountry();
        CuMemberExt member = cuMemberService.getMemberById(pkMember);
        //查询实名认证信息原证件图
        CuMemberAuthenticationVO authenticationVO = CuMemberAuthenticationVO.builder().pkCountry(pkCountry).pkMember(pkMember).build();
        CuMemberAuthenticationVO cuMemberAuthenticationVO = cuMemberAuthenticationService.selectCuMemberAuthenticationByPkMember(authenticationVO);
        if (null != cuMemberAuthenticationVO) {
            idBack = cuMemberAuthenticationVO.getIdBack();
            idFront = cuMemberAuthenticationVO.getIdFront();
        }
        ServiceChargeDTO serviceChargeInfo = getServiceChargeInfo(pkCountry);
        BigDecimal cost = null != serviceChargeInfo ? serviceChargeInfo.getCost() : BigDecimal.ZERO;
        DomicileChangeVO domicileChangeVO = DomicileChangeVO.builder().memberCode(member.getMemberCode())
                .memberName(member.getMemberName()).phone(member.getPhone()).amount(cost).pkAccount(serviceChargeInfo.getPkAccount())
                .idBack(idBack).idFront(idFront).build();
        return AjaxResult.success(domicileChangeVO);
    }

    /**
     * 是否存在审核的数据
     *
     * @param domicileChangeVO 户籍变更信息
     * @return AjaxResult
     */
    private AjaxResult isExistApprovalData(DomicileChangeVO domicileChangeVO) {
        CuSelfServiceLog cuSelfServiceLog = new CuSelfServiceLog();
        cuSelfServiceLog.setPkCountry(domicileChangeVO.getPkCountry());
        cuSelfServiceLog.setEditType(EApprovalBusiness.DOMICILE_CHANGE.getValue());
        cuSelfServiceLog.setPkMember(domicileChangeVO.getPkMember());
        Integer check = serviceLogService.checkSelfService(cuSelfServiceLog);
        if (check > 0) {
            return AjaxResult.error(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_UPDATE_CODE_REPEAT));
        }
        return AjaxResult.success();
    }

    /**
     * 查询手续费
     *
     * @param pkCountry 国家pID
     * @return ServiceChargeDTO
     */
    private ServiceChargeDTO getServiceChargeInfo(Integer pkCountry) {
        //查询扣费金额，账户信息
        ServiceChargeDTO serviceChargeDTO = new ServiceChargeDTO();
        serviceChargeDTO.setType(EApprovalBusiness.DOMICILE_CHANGE.getValue());
        serviceChargeDTO.setPkCountry(pkCountry);
        serviceChargeDTO.setQuantity(MagicNumberConstants.CHANGE_NUM);
        return serviceChargeServiceApi.getServiceChargeByType(serviceChargeDTO).getData();
    }

    /**
     * 查询余额是否充足
     *
     * @param domicileChangeVO 户籍变更信息
     * @return AjaxResult
     */
    private AjaxResult isAccountBalance(DomicileChangeVO domicileChangeVO) {
        List<MemberAmountDTO> memberAmountDTOList = new ArrayList<>();
        memberAmountDTOList.add(MemberAmountDTO.builder().pkMember(domicileChangeVO.getPkMember()).tradeAmount(domicileChangeVO.getAmount()).build());
        BusinessCommissionDTO businessCommissionDTO = BusinessCommissionDTO.builder().pkAccount(domicileChangeVO.getPkAccount()).memberAmountDTOList(memberAmountDTOList).build();
        List<MemberBalanceDTO> memberBalanceList = cuMemberTradeService.selectBalanceNotEnoughMember(businessCommissionDTO);
        if (CollectionUtil.isNotEmpty(memberBalanceList)) {
            return AjaxResult.error(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_BALANCE_INSUFFICIENT));
        }
        return AjaxResult.success();
    }

    /**
     * 是否配置审批人信息
     *
     * @param pkCountry 国家ID
     * @return AjaxResult
     */
    private AjaxResult isConfigApprovalInfo(Integer pkCountry, DomicileChangeVO domicileChangeVO) {
        Map<Integer, ApprovalInfoDTO> approvalInfoMap = iApprovalServiceApi.queryApprovalInfo(Collections.singletonList(EApprovalBusiness.DOMICILE_CHANGE.getValue()), pkCountry).getData();
        // 根据审批业务类型判断是否配置审批流程
        ApprovalInfoDTO approvalInfo = approvalInfoMap.get(EApprovalBusiness.DOMICILE_CHANGE.getValue());
        if (null == approvalInfo || CollectionUtil.isEmpty(approvalInfo.getItemList())) {
            log.error("{} 提交认证失败，未配置审批流程", EApprovalBusiness.DOMICILE_CHANGE.getLabel());
            return AjaxResult.error("提交认证失败，请联系客服");
        }
        List<Long> userList = approvalInfo.getItemList().stream().map(ApprovalItemInfoDTO::getPkUser).collect(Collectors.toList());
        domicileChangeVO.setUserIdList(userList);
        return AjaxResult.success();
    }

}
