package com.hzs.activity.policy.service.impl;

import cn.hutool.core.collection.CollectionUtil;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.activity.base.param.ActivityParam;
import com.hzs.activity.base.service.IAcApprovalLogService;
import com.hzs.activity.base.service.IAcBaseConfigService;
import com.hzs.activity.base.service.IActivityService;
import com.hzs.activity.policy.mapper.AcPolicyConfigMapper;
import com.hzs.activity.policy.param.PolicyConfigParam;
import com.hzs.activity.policy.service.IAcPolicyConfigService;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.EAccount;
import com.hzs.common.core.enums.ETradeClassify;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.constant.msg.DocumentMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.exception.base.BaseException;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.common.domain.activity.base.AcApprovalLog;
import com.hzs.common.domain.activity.base.AcBaseConfig;
import com.hzs.common.domain.member.account.CuMemberTrade;
import com.hzs.common.domain.policy.AcPolicyConfig;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.member.account.IMemberAccountServiceApi;
import com.hzs.member.account.IMemberTradeServiceApi;
import com.hzs.system.config.IAccountServiceApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;
import com.hzs.system.sys.dto.ApprovalSubmitDTO;
import com.hzs.system.sys.dto.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 海外政策币配置 服务实现类
 * </p>
 *
 * @author hzs
 * @since 2023-12-26
 */
@Slf4j
@Service
public class AcPolicyConfigServiceImpl extends ServiceImpl<AcPolicyConfigMapper, AcPolicyConfig> implements IAcPolicyConfigService {
    @Autowired
    private IAcApprovalLogService acApprovalLogService;
    @Autowired
    private IAcBaseConfigService baseConfigService;
    @Autowired
    private IAcPolicyConfigService policyConfigService;

    @Autowired
    private IActivityService activityService;
    @DubboReference
    private IApprovalServiceApi iApprovalServiceApi;
    @DubboReference
    private IMemberTradeServiceApi iMemberTradeServiceApi;
    @DubboReference
    private IMemberAccountServiceApi iMemberAccountServiceApi;
    @DubboReference
    private IAccountServiceApi accountServiceApi;

    /**
     * 批量新增/修改
     * @param policyConfigParam
     * @param pkCountry
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAll(PolicyConfigParam policyConfigParam, Integer pkCountry) {
        ActivityParam activityParam = policyConfigParam.getActivityParam();
        Long pkUser = SecurityUtils.getUserId();
        // 新增列表
        List<AcPolicyConfig> saveList = new ArrayList<>();
        // 修改列表
        List<AcPolicyConfig> updateList = new ArrayList<>();
        for (AcPolicyConfig acPolicyConfig : policyConfigParam.getPolicyConfigList()) {
            if (acPolicyConfig.getPkId() == null){
                acPolicyConfig.setCreationTime(DateUtils.currentDateTime());
                acPolicyConfig.setPkCreator(pkUser);
                acPolicyConfig.setPkCountry(pkCountry);
                saveList.add(acPolicyConfig);
            }else {
                acPolicyConfig.setModifiedTime(DateUtils.currentDateTime());
                acPolicyConfig.setPkModified(pkUser);
                updateList.add(acPolicyConfig);
            }
        }
        AcBaseConfig baseConfig = null;
        if (activityParam.getPkId() != null){
            // 修改基础配置
             baseConfig = activityService.updateBaseConfig(activityParam);
        }else {
            // 增加基础配置
            activityParam.setPkCountry(pkCountry);
            activityParam.setPkCreator(SecurityUtils.getUserId());
            activityParam.setActType(EActType.POLICY.getValue());
            activityParam.setCreationTime(DateUtils.currentDateTime());
            baseConfig = activityService.saveBaseConfig(activityParam);
        }
        saveList.addAll(updateList);
        if (saveList != null && saveList.size() > 0){
            deleteByPkCountryAll(pkCountry,null,baseConfig.getPkId());
            for (AcPolicyConfig acPolicyConfig : saveList) {
                acPolicyConfig.setPkBaseId(baseConfig.getPkId());
            }
            saveBatch(saveList);
         //   saveBatch(updateList);
        }

    }

    /**
     * 提交政策币赠送签呈
     * @param param
     * @param loginUser
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String policyConfigSubmit(PolicyConfigParam param, LoginUser loginUser) {
        // 会员ID
        Long userId = SecurityUtils.getUserId();
        // 所属国家
        Integer pkCountry = SecurityUtils.getPkCountry();
        if (loginUser == null){
            loginUser = new LoginUser();
            loginUser.setUserId(userId);
            loginUser.setDataCountry(pkCountry);
        }

        // 业务编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ACTIVITY_CODE);

        // 批量保存日志
        List<AcApprovalLog> approvalLogList = new ArrayList<>();
        // 活动审批日志
        AcApprovalLog acApprovalLog = new AcApprovalLog();
        acApprovalLog.setApprovalType(EApprovalBusiness.POLICY_GIVE.getValue());
        acApprovalLog.setBusinessCode(businessCode);
        acApprovalLog.setPkCreator(userId);
        acApprovalLog.setPkCountry(pkCountry);
        acApprovalLog.setAfterData(JSONUtil.toJsonStr(param));
        if (null != param.getActivityParam().getPkId()) {
            acApprovalLog.setPkBusiness(param.getActivityParam().getPkId());
        }
        approvalLogList.add(acApprovalLog);

        if (acApprovalLogService.saveBatch(approvalLogList)) {
            // 保存审批日志成功，提交签呈
            // 提交签呈处理
            R<String> resultR = iApprovalServiceApi.submitOrder(
                    ApprovalSubmitDTO.builder()
                            .eApprovalBusiness(EApprovalBusiness.POLICY_GIVE)
                            .businessCode(businessCode)
                            .businessData(JSONUtil.toJsonStr(param))
                            .signType(ESignType.getEnumByValue(param.getSignType()))
                            .userIdList(param.getUserIdList())
                            .sendIdList(param.getSendIdList())
                            .remark(param.getRemark())
                            .fileList(param.getFileList())
                            .build(),
                    loginUser,
                    null
            );
            if (resultR.isSuccess()) {
                return TransactionUtils.getContent(CommonMsgConstants.OPERATION_SUCCESS);
            }
            throw new BaseException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + ": " + resultR.getMsg());
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }

    /**
     * 签呈审批通过
     * @param businessResult
     * @return
     */
    @Override
    public String ApprovalAgree(ApprovalBusinessResultDTO businessResult) {
        EApprovalBusiness eApprovalBusiness = businessResult.getEApprovalBusiness();
        String businessCode = businessResult.getBusinessCode();
        LoginUser loginUser = businessResult.getLoginUser();
        AcApprovalLog approvalLog = acApprovalLogService.queryApprovalLog(eApprovalBusiness, businessCode, loginUser.getDataCountry());
        if (null == approvalLog) {
            return "审批数据不存在！";
        }
        String data = approvalLog.getAfterData();
        PolicyConfigParam policyConfigParam = JSONUtil.toBean(data, PolicyConfigParam.class);
        if (policyConfigParam.getControlType().equals(EControlType.SAVE.getValue())
    || policyConfigParam.getControlType().equals(EControlType.MODIFY.getValue())){
            saveAll(policyConfigParam,loginUser.getDataCountry());
        }else if (policyConfigParam.getControlType().equals(EControlType.DELETE.getValue())){
            deletePolicy(policyConfigParam,loginUser.getDataCountry());
        }

        acApprovalLogService.updateApprovalLog(businessResult.getEApprovalBusiness(), businessResult.getBusinessCode(), loginUser.getDataCountry(), loginUser.getUserId(), EApproveRechargeStatus.AGREE, businessResult.getApproveRemark());
        log.error("赠送政策币同意处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);

    }

    /**
     * 删除
     * @param policyConfigParam
     * @param dataCountry
     */
    private void deletePolicy(PolicyConfigParam policyConfigParam, Integer pkCountry) {
        Long pkBaseId = policyConfigParam.getActivityParam().getPkId();

        baseConfigService.removeById(pkBaseId);
        QueryWrapper<AcPolicyConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PK_BASE_ID",pkBaseId);
        policyConfigService.remove(queryWrapper);
    }

    /**
     * 签呈审核驳回
     * @param resultDTO
     */
    @Override
    public String ApprovalReject(ApprovalBusinessResultDTO resultDTO) {
        // 用户ID
        Long userId = resultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = resultDTO.getLoginUser().getDataCountry();

        List<AcApprovalLog> approvalLogList = acApprovalLogService.queryApprovalLogList(resultDTO.getEApprovalBusiness(), resultDTO.getBusinessCode(), pkCountry);
        // 一批审批可能有多个
        AcApprovalLog approvalLog = approvalLogList.get(0);
        if (null == approvalLog) {
            log.error("赠送政策币签呈驳回失败");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
        }

        if (acApprovalLogService.updateApprovalLog(resultDTO.getEApprovalBusiness(), resultDTO.getBusinessCode(), pkCountry, userId, EApproveRechargeStatus.REJECT, resultDTO.getApproveRemark())) {
            return null;
        }
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    /**
     * 删除所有规则
     * @param pkCountry
     */
    private void deleteByPkCountryAll(Integer pkCountry,List<Long> notIdlList,Long pkBaseId) {
        baseMapper.deleteByPkCountryAll(pkCountry,notIdlList,pkBaseId);
    }

    @Override
    public void handleOrderPolicyActivity(SaOrderExt saOrderExt) {
        AcPolicyConfig acPolicyConfig = baseMapper.queryLastConfig(saOrderExt.getOrderAchieve(), saOrderExt.getPayTime(), saOrderExt.getPkCountry());
        if (null == acPolicyConfig) {
            // 没有符合规则
            log.error("注册赠送政策币没有符合规则");
        } else {
            // 有符合规则，进行处理
            BigDecimal policyCurrency = acPolicyConfig.getPolicycurrency();
            // 赠送的政策币（美金），大于0则进行处理
            if (policyCurrency.compareTo(BigDecimal.ZERO) > 0) {
                // 根据订单赠送政策币
                R resultR = iMemberAccountServiceApi.handleOrderPolicyActivity(saOrderExt, policyCurrency);
                if (!resultR.isSuccess()) {
                    log.error(resultR.getMsg());
                }
            }
        }
    }

    @Override
    public void backOrderPolicyActivity(SaOrderExt saOrderExt) {
        // 交易明细列表
        List<CuMemberTrade> memberTradeList = iMemberTradeServiceApi.querySourceCodeLastTrade(saOrderExt.getPkCreator(), saOrderExt.getOrderCode(), ETradeClassify.RECHARGE.getValue()).getData();
        if (CollectionUtil.isNotEmpty(memberTradeList)) {
            // 政策币
            log.info("撤单活动MQ异步处理 activity：{}" , saOrderExt);
            BdAccount bdAccount = accountServiceApi.getBdAccountByFieldValue(saOrderExt.getPkCountry(), EAccount.POLICY.getValue()).getData();
            for (CuMemberTrade cuMemberTrade : memberTradeList) {
                if (cuMemberTrade.getPkAccount().equals(bdAccount.getPkId())) {
                    // 活动充值政策币，需要回退处理
                    R resultR = iMemberAccountServiceApi.backOrderPolicyActivity(saOrderExt, cuMemberTrade);
                    if (!resultR.isSuccess()) {
                        log.error(resultR.getMsg());
                    }
                    break;
                }
            }
        }
    }

}
