package com.hzs.system.sys.controller.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzs.activity.base.IActivityApprovalServiceApi;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.CacheConstants;
import com.hzs.common.core.constant.SystemFieldConstants;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.constant.msg.DocumentMsgConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.service.RedisService;
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.system.sys.SysApprovalBusinessData;
import com.hzs.common.domain.system.sys.SysApprovalBusinessDetail;
import com.hzs.common.domain.system.sys.SysApprovalBusinessFile;
import com.hzs.common.domain.system.sys.SysUser;
import com.hzs.common.domain.system.sys.ext.SysApprovalBusinessExt;
import com.hzs.common.domain.system.sys.ext.SysApprovalBusinessSendExt;
import com.hzs.common.security.service.UserTokenService;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.member.base.ICuAwardsControlServiceApi;
import com.hzs.member.base.ICuMemberAchieveLogServiceApi;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.member.base.IUpPolicyCurrencyServiceApi;
import com.hzs.member.base.dto.CuAwardsControlDTO;
import com.hzs.member.base.dto.NotActivePointDTO;
import com.hzs.member.base.dto.UpPolicyCurrencyDTO;
import com.hzs.member.handlebusiness.ICuHandleBusinessServiceApi;
import com.hzs.member.handlebusiness.dto.AnalysisBusinessAppealParam;
import com.hzs.member.store.ICuStoreServiceApi;
import com.hzs.member.store.dto.StoreDto;
import com.hzs.sale.pub.ISaleApprovalServiceApi;
import com.hzs.system.sys.param.ApprovalBusinessParam;
import com.hzs.system.sys.service.*;
import com.hzs.system.sys.vo.ApprovalBusinessVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 审批业务处理
 */
@RestController
@RequestMapping("/manage/approval-business")
public class SysApprovalBusinessController extends BaseController {

    @Autowired
    private ISysApprovalBusinessService iSysApprovalBusinessService;
    @Autowired
    private ISysApprovalBusinessDataService iSysApprovalBusinessDataService;
    @Autowired
    private ISysApprovalBusinessSendService iSysApprovalBusinessSendService;
    @Autowired
    private ISysApprovalBusinessFileService iSysApprovalBusinessFileService;
    @Autowired
    private IApprovalService iApprovalService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private RedisService redisService;

    @DubboReference
    ICuHandleBusinessServiceApi iCuHandleBusinessServiceApi;
    @DubboReference
    ISaleApprovalServiceApi iSaleApprovalServiceApi;
    @DubboReference
    ICuMemberAchieveLogServiceApi achieveLogServiceApi;
    @DubboReference
    ICuAwardsControlServiceApi controlServiceApi;
    @DubboReference
    IActivityApprovalServiceApi iActivityApprovalServiceApi;
    @DubboReference
    IUpPolicyCurrencyServiceApi upPolicyCurrencyServiceApi;
    @DubboReference
    IMemberServiceApi iMemberServiceApi;
    @DubboReference
    ICuStoreServiceApi iCuStoreServiceApi;

    /**
     * 获取审批详情
     *
     * @param approvalCode 审批单号
     * @return
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_DETAIL, method = EOperationMethod.SELECT)
    @GetMapping("/detail/{approvalCode}")
    public AjaxResult detail(@PathVariable("approvalCode") String approvalCode) {
        // 审批详情
        SysApprovalBusinessExt approvalBusinessExt = iSysApprovalBusinessService.queryByApprovalCode(approvalCode);
        if (null == approvalBusinessExt) {
            // 签呈信息不存在
            return AjaxResult.error(TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST));
        }

        // 签呈抄送列表
        Map<Long, List<SysApprovalBusinessSendExt>> sendMap = iSysApprovalBusinessSendService.approvalSendMap(Collections.singletonList(approvalBusinessExt.getPkId()));

        // 多级未审批，只有第一级进行补全，后面不做处理
        for (SysApprovalBusinessDetail sysApprovalBusinessDetail : approvalBusinessExt.getDetailList()) {
            if (null == sysApprovalBusinessDetail.getStatus()) {
                if (SecurityUtils.getUserId().equals(sysApprovalBusinessDetail.getPkUser())) {
                    // 当前需要登录管理员审批时，需要处理显示为可编辑状态
                    SysUser sysUser = iSysUserService.queryUserAndDeptName(sysApprovalBusinessDetail.getPkUser());
                    sysApprovalBusinessDetail.setApproverDept(sysUser.getDeptName());
                    sysApprovalBusinessDetail.setStatus(0);
                }
                break;
            }
        }

        // 封装返回前台数据
        ApprovalBusinessVO approvalBusinessVO = BeanUtil.copyProperties(approvalBusinessExt, ApprovalBusinessVO.class);

        List<SysApprovalBusinessSendExt> approvalSendList = sendMap.get(approvalBusinessExt.getPkId());
        if (CollectionUtil.isNotEmpty(approvalSendList)) {
            // 处理抄送人
            StringBuilder sendSb = new StringBuilder();
            for (SysApprovalBusinessSendExt sysApprovalBusinessSend : approvalSendList) {
                sendSb.append(",").append(sysApprovalBusinessSend.getNickName());
            }
            approvalBusinessVO.setSendStr(sendSb.substring(1));
        }

        // 审批附件
        QueryWrapper<SysApprovalBusinessFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PK_APPROVAL_BUSINESS", approvalBusinessExt.getPkId());
        queryWrapper.orderByAsc(SystemFieldConstants.PK_ID);
        List<SysApprovalBusinessFile> fileList = iSysApprovalBusinessFileService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(fileList)) {
            approvalBusinessVO.setFilePathList(fileList.stream().map(SysApprovalBusinessFile::getFilePath).collect(Collectors.toList()));
        }

        // 调用各服务，查询显示内容
        switch (EApprovalType.getEnumByApprovalBusinessValue(approvalBusinessExt.getApprovalBusiness())) {
            case MEMBER_BUSINESS:
                // 会员相关
                if (approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.MEMBER_ACHIEVE.getValue()) {
                    // 注水业绩审核列表信息
                    AnalysisBusinessAppealParam analysisBusinessAppealParam1 = new AnalysisBusinessAppealParam();
                    analysisBusinessAppealParam1.setBusinessNo(approvalBusinessExt.getBusinessCode());
                    analysisBusinessAppealParam1.setEditType(approvalBusinessExt.getApprovalBusiness());
                    analysisBusinessAppealParam1.setPkCountry(SecurityUtils.getPkCountry());
                    R achieveLog = achieveLogServiceApi.memberAchieveLog(analysisBusinessAppealParam1);
                    if (achieveLog.isSuccess()) {
                        if (achieveLog.getData() != null) {
                            approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(achieveLog.getData()));
                        }
                    }
                } else if (approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.AWARDS_CONTROL_SAVE.getValue() ||
                        approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.AWARDS_CONTROL_MODIFY.getValue() ||
                        approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.AWARDS_CONTROL_DELETE.getValue()) {
                    //真实奖衔控制审核列表
                    AnalysisBusinessAppealParam analysisBusinessAppealParam1 = new AnalysisBusinessAppealParam();
                    analysisBusinessAppealParam1.setBusinessNo(approvalBusinessExt.getBusinessCode());
                    R<List<CuAwardsControlDTO>> controlList = controlServiceApi.awardsControlList(analysisBusinessAppealParam1);
                    if (controlList.isSuccess()) {
                        if (controlList.getData() != null) {
                            approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(controlList.getData()));
                        }
                    }
                } else if (approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.CU_STORE_SAVE.getValue() ||
                        approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.CU_STORE_MODIFY.getValue() ||
                        approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.CU_STORE_DELETE.getValue()) {
                    //会员店铺配置审核列表
                    AnalysisBusinessAppealParam analysisBusinessAppealParam1 = new AnalysisBusinessAppealParam();
                    analysisBusinessAppealParam1.setBusinessNo(approvalBusinessExt.getBusinessCode());
                    R<StoreDto> store = iCuStoreServiceApi.getCuStoreByBusinessNo(analysisBusinessAppealParam1);
                    if (store.isSuccess()) {
                        if (store.getData() != null) {
                            approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(store.getData()));
                        }
                    }
                } else if (approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.POLICY_CURRENCY_YES_NO.getValue()) {
                    //修改政策币审核列表
                    AnalysisBusinessAppealParam analysisBusinessAppealParam1 = new AnalysisBusinessAppealParam();
                    analysisBusinessAppealParam1.setBusinessNo(approvalBusinessExt.getBusinessCode());
                    R<List<UpPolicyCurrencyDTO>> pgpList = upPolicyCurrencyServiceApi.policyCurrencyList(analysisBusinessAppealParam1);
                    if (pgpList.isSuccess()) {
                        if (pgpList.getData() != null) {
                            approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(pgpList.getData()));
                        }
                    }
                } else if (approvalBusinessExt.getApprovalBusiness() == EApprovalBusiness.NOT_ACTIVE_POINT.getValue()) {
                    //未激活点位审核列表
                    AnalysisBusinessAppealParam analysisBusinessAppealParam1 = new AnalysisBusinessAppealParam();
                    analysisBusinessAppealParam1.setBusinessNo(approvalBusinessExt.getBusinessCode());
                    R<List<NotActivePointDTO>> zeroList = iMemberServiceApi.notActiveByBusinessList(analysisBusinessAppealParam1);
                    if (zeroList.isSuccess()) {
                        if (zeroList.getData() != null) {
                            approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(zeroList.getData(), JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss")));
                        }
                    }
                } else {
                    R memberR = iCuHandleBusinessServiceApi.analysisBusinessAppeal(AnalysisBusinessAppealParam.builder()
                            .businessNo(approvalBusinessExt.getBusinessCode())
                            .editType(approvalBusinessExt.getApprovalBusiness())
                            .pkCountry(SecurityUtils.getPkCountry())
                            .signSource(approvalBusinessExt.getSignSource())
                            .toLanguageTag(LocaleContextHolder.getLocale().toLanguageTag())
                            .build());
                    if (memberR.isSuccess()) {
                        if (null != memberR.getData()) {
                            approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(memberR.getData()));
                        }
                    }
                }
                break;
            case ORDER_BUSINESS:
                // 订单相关
                R orderR = iSaleApprovalServiceApi.queryApprovalData(EApprovalBusiness.getEnumByValue(approvalBusinessExt.getApprovalBusiness()), approvalBusinessExt.getBusinessCode(), LocaleContextHolder.getLocale().toLanguageTag());
                if (orderR.isSuccess()) {
                    if (null != orderR.getData()) {
                        approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(orderR.getData()));
                    }
                }
                break;
            case FINANCE_BUSINESS:
            case NOTICE_BUSINESS:
                // 财务相关、公告站内信（直接取冗余在审批中的信息）
                QueryWrapper<SysApprovalBusinessData> dataQueryWrapper = new QueryWrapper<>();
                dataQueryWrapper.eq("PK_APPROVAL_BUSINESS", approvalBusinessExt.getPkId());
                SysApprovalBusinessData sysApprovalBusinessData = iSysApprovalBusinessDataService.getOne(dataQueryWrapper);
                if (null != sysApprovalBusinessData) {
                    approvalBusinessVO.setBusinessData(sysApprovalBusinessData.getBusinessData());
                }
                break;
            case ACTIVITY_BUSINESS:
                // 活动服务信息处理
                R activityR = iActivityApprovalServiceApi.queryApprovalData(EApprovalBusiness.getEnumByValue(approvalBusinessExt.getApprovalBusiness()), approvalBusinessExt.getBusinessCode(), SecurityUtils.getPkCountry());
                if (activityR.isSuccess()) {
                    if (null != activityR.getData()) {
                        JSONConfig jsonConfig = JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss");
                        approvalBusinessVO.setBusinessData(JSONUtil.toJsonStr(activityR.getData(), jsonConfig));
                    }
                }
                break;
        }
        return AjaxResult.success(approvalBusinessVO);
    }

    /**
     * 审批
     *
     * @param param 审批入参
     * @return
     */
    @RepeatSubmitSimple
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_DETAIL, method = EOperationMethod.APPROVAL)
    @PutMapping("/approval")
    public AjaxResult approval(@RequestBody ApprovalBusinessParam param) {
        if (StringUtils.isEmpty(param.getApprovalCode()) || null == param.getApproveOperation()) {
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }

        // 签呈审批时，锁定的key
        String approvalKey = CacheConstants.APPROVAL_LOCK + param.getApprovalCode();
        try {
            // 签呈审批时，锁定8秒，防止出现重复操作
            if (redisService.lockKeyOnce(approvalKey, 8)) {
                // 查询审批业务信息
                SysApprovalBusinessExt approvalBusinessExt = iSysApprovalBusinessService.queryByApprovalCode(param.getApprovalCode());
                if (null == approvalBusinessExt || CollectionUtils.isEmpty(approvalBusinessExt.getDetailList())) {
                    // 签呈信息不存在
                    return AjaxResult.error(TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST));
                }
                if (EApproveStatus.REJECTED.getValue() == approvalBusinessExt.getApprovalStatus()) {
                    // 签呈审批已经驳回
                    return AjaxResult.error(TransactionUtils.getContent(DocumentMsgConstants.SIGN_APPROVAL_REJECT));
                } else if (EApproveStatus.FINISH.getValue() == approvalBusinessExt.getApprovalStatus()) {
                    // 签呈审批已完成
                    return AjaxResult.error(TransactionUtils.getContent(DocumentMsgConstants.SIGN_APPROVAL_AGREE));
                }

                String str = iApprovalService.approval(approvalBusinessExt, param.getApproveOperation(), param.getRemark(), userTokenService.getLoginUser());

                if (null == str) {
                    return AjaxResult.success();
                }
                return AjaxResult.error(str);
            }
        } finally {
            // 执行结束释放锁
            redisService.unlock(approvalKey);
        }
        return AjaxResult.error("数据正在操作中，请稍后刷新重试");
    }

}
