package com.muchinfo.mtp3century.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.muchinfo.mtp.proto.Common;
import com.muchinfo.mtp.proto.PerformanceMI1;
import com.muchinfo.mtp3century.service.ICommonService;
import com.muchinfo.mtp3century.service.IPerformanceService;
import com.muchinfo.mtp3common.enumtype.Constants;
import com.muchinfo.mtp3common.enumtype.FunCodeConstants;
import com.muchinfo.mtp3common.enumtype.MessageType;
import com.muchinfo.mtp3common.enumtype.SysConstants;
import com.muchinfo.mtp3common.utils.SerialNumberUtils;
import com.muchinfo.mtp3century.utils.AjaxResult;
import com.muchinfo.mtp3common.vo.Calculator;
import com.muchinfo.mtp3common.vo.PageResult;
import com.muchinfo.mtp3common.vo.ProtoHelper;
import com.muchinfo.mtp3interface.mapper.*;
import com.muchinfo.mtp3pojos.entity.*;
import com.muchinfo.mtp3pojos.vo.ProtoErrorCodes;
import com.muchinfo.mtp3pojos.vo.performance.*;
import com.muchinfo.mtp3pojos.vo.query.deliveryorder.SettlementDealDetailParam;
import com.muchinfo.mtp3pojos.vo.query.deliveryorder.SettlementDealDetailResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class PerformanceServiceImpl implements IPerformanceService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Resource
    private ISystemmanagerMapper iSystemmanagerMapper;
    @Resource
    private ICommonService iCommonService;
    @Resource
    private IPerformanceplanMapper iPerformanceplanMapper;
    @Resource
    private IPerformancebreachMapper iPerformancebreachMapper;
    @Resource
    private IHisPerformancebreachMapper iHisPerformancebreachMapper;
    @Resource
    private IUseraccountMapper iUseraccountMapper;
    @Resource
    private IPerformancestepMapper iPerformancestepMapper;
    @Resource
    private IPerformancesteptypeMapper iPerformancesteptypeMapper;
    @Resource
    private ITradeOrderdetailMapper iTradeOrderdetailMapper;
    @Resource
    private ITradeExercisedetailMapper iTradeExercisedetailMapper;
    @Resource
    private IHisTradeExercisedetailMapper iHisTradeExercisedetailMapper;
    @Resource
    private IGoodsMapper iGoodsMapper;
    @Resource
    private IPerformancebreachapplyMapper iPerformancebreachapplyMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public PageResult<PayPerformanceResult> query(PayPerformanceParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (!SysConstants.SYS_TYPE_MANAGE.equals(systemmanager.getReletype())) {
            if (("," + param.getOrgztypes() + ",").contains(",3,")) {
                param.setParentuserid(systemmanager.getAreauserid());
            }
        }
        param.setAccountid(systemmanager.getAreauserid());
        PageResult<PayPerformanceResult> pageResult = new PageResult<>();
        IPage<PayPerformanceResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<PayPerformanceResult> resultIPage;
        if (param.getIshis() != null && param.getIshis() == 1) {
            resultIPage = iPerformanceplanMapper.query(page, param);
        } else {
            resultIPage = iPerformanceplanMapper.queryHis(page, param);
        }
        for (PayPerformanceResult record : resultIPage.getRecords()) {
            String sysparm = iCommonService.getSysparmById(SysConstants.SYSPARAM_CODE_DELAY);
            if (StringUtils.isNotBlank(sysparm)) {
                record.setDelayapply(sysparm);
            } else {
                record.setDelayapply("1");
            }
            record.setAccountid(systemmanager.getAreauserid());
        }
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(resultIPage.getPages());
        pageResult.setCurrent(resultIPage.getCurrent());
        pageResult.setTotal(resultIPage.getTotal());
        pageResult.setPageSize(resultIPage.getSize());
        pageResult.setData(resultIPage.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult<PayPerformanceDetailResult> view(String planid, Integer sellorbuy, String histradedate, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        PayPerformanceDetailResult result = new PayPerformanceDetailResult();
        PayPerformancePlanResult plan;
        if (StringUtils.isEmpty(histradedate)) {
            plan = iPerformanceplanMapper.queryPerformancePlanDetail(planid);
            //违约信息
            result.setPerformancebreach(iPerformancebreachMapper.selectOne(new QueryWrapper<Performancebreach>()
                    .eq("planid", planid)));
        } else {
            plan = iPerformanceplanMapper.getHisPerformancePlanDetail(planid, histradedate);
            //违约信息
            result.setHisPerformancebreach(iHisPerformancebreachMapper.selectList(new QueryWrapper<HisPerformancebreach>()
                    .eq("planid", planid)
                    .eq("isvaliddata", 1)
                    .eq("histradedate", histradedate)).get(0));
        }
        //履约延期
        result.setPerformanceDelayResult(iPerformanceplanMapper.queryPerformanceDelayList(planid));

        Long accountid = null;
        if (plan != null) {
            plan.setBuyAccountName(iUseraccountMapper.selectUserName(plan.getBuyAccountId()));
            plan.setSellAccountName(iUseraccountMapper.selectUserName(plan.getSellAccountId()));
            plan.setWrtransferusername(iUseraccountMapper.selectOrganName(plan.getWrTransferUserId()));
            plan.setPerformancesteps(iPerformancestepMapper.selectList(new QueryWrapper<Performancestep>().eq("planid", planid).orderByAsc("stepindex")));

            if (StringUtils.isNotBlank(plan.getBuyerInfo())) {
                String buyerInfo = plan.getBuyerInfo();
                try {
                    buyerInfo = buyerInfo.replaceAll("&quot;", "\"");
                    JSONObject json = JSONObject.parseObject(buyerInfo);
                    String contactinfo = json.getString("ContactInfo");
                    String receiptaccount = json.getString("ReceiptInfo");
                    String address = json.getString("ReceiveInfo");
                    buyerInfo = "联络信息：" + contactinfo + "<br/>" + "收货地址：" + address + "<br/>" + "发票信息：" + receiptaccount;
                } catch (Exception e) {
                    log.info("买方信息转换json失败，失败原因：" + e.getMessage());
                }
                plan.setBuyerInfo(buyerInfo);
            }
            if (StringUtils.isNotBlank(plan.getSellerInfo())) {
                String sellerInfo = plan.getSellerInfo();
                try {
                    sellerInfo = sellerInfo.replaceAll("&quot;", "\"");
                    JSONObject json = JSONObject.parseObject(sellerInfo);
                    String contactinfo = json.getString("ContactInfo");
                    sellerInfo = "联络信息：" + contactinfo;
                } catch (Exception e) {
                    log.info("卖方信息转换json失败，失败原因：" + e.getMessage());
                }
                plan.setSellerInfo(sellerInfo);
            }
            if (sellorbuy != null) {
                if (sellorbuy == 1) {
                    accountid = plan.getBuyAccountId();
                } else if (sellorbuy == 2) {
                    accountid = plan.getSellAccountId();
                }
                if (accountid != null && !iCommonService.checkTaAccountReport(systemmanager, accountid)) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
                }
            }
            result.setPayPerformancePlanResult(plan);
        }

        List<Performancesteptype> list = iPerformancesteptypeMapper.selectList(new QueryWrapper<>());
        Map<Integer, String> map = new HashMap<Integer, String>();
        list.forEach(p -> {
            map.put(p.getSteptypeid(), p.getSteptypename());
        });
        result.setSteptype(map);

        Performancesteptype pst10 = iPerformancesteptypeMapper.selectOne(new QueryWrapper<Performancesteptype>().eq("steptypeid", 10));
        if (Objects.nonNull(pst10))
            result.setIsHasStep10(1);
        else
            result.setIsHasStep10(0);

        Performancesteptype pst12 = iPerformancesteptypeMapper.selectOne(new QueryWrapper<Performancesteptype>().eq("steptypeid", 12));
        if (Objects.nonNull(pst12))
            result.setIsHasStep10(1);
        else
            result.setIsHasStep10(0);

        //履约商品
        int buyorsell = 0; //买
        PayPerformanceRelatedInfoResult relatedInfoResult = new PayPerformanceRelatedInfoResult();
        if (plan != null && plan.getExecuteside() != null && plan.getExecuteside() == 2)
            buyorsell = 1; //卖
        if (plan != null && plan.getPerformancetype() == 1) {
            SettlementDealDetailParam dealDetailParam = new SettlementDealDetailParam();
            SettlementDealDetailResult detailResult;
            //交割
            if (StringUtils.isEmpty(histradedate)) {
                //当前
                dealDetailParam.setBuyorsell(sellorbuy);
                dealDetailParam.setDeliveryid(plan.getRelatedOrderId());
                detailResult = iTradeOrderdetailMapper.settlementDealDetail(dealDetailParam);
            } else {
                //历史
                dealDetailParam.setBuyorsell(sellorbuy);
                dealDetailParam.setDeliveryid(plan.getRelatedOrderId());
                dealDetailParam.setHistradedate(histradedate);
                detailResult = iTradeOrderdetailMapper.settlementDealDetail(dealDetailParam);
            }
            relatedInfoResult.setWrstandardcode(detailResult.getWrstandardcode());
            relatedInfoResult.setWarehousename(detailResult.getWarehousename());
            relatedInfoResult.setWrstandardname(detailResult.getWrstandardname());
            relatedInfoResult.setDeliverytotalamount(detailResult.getDeliverytotalamount());
            result.setRelatedInfoResult(relatedInfoResult);
        } else if (plan != null && (plan.getPerformancetype() == 2 || plan.getPerformancetype() == 3)) {

        } else if (plan != null && plan.getPerformancetype() == 5) {
            //挂牌期权
            if (StringUtils.isEmpty(histradedate)) {
                TradeExercisedetail tradeExercisedetail = iTradeExercisedetailMapper.selectOne(new QueryWrapper<TradeExercisedetail>().eq("tradeid", plan.getRelatedOrderId()));
                Goods goods = iGoodsMapper.selectOne(new QueryWrapper<Goods>().eq("goodsid", tradeExercisedetail.getGoodsid()));
                relatedInfoResult.setGoodsname(goods.getGoodsname());
                relatedInfoResult.setBuyerout(tradeExercisedetail.getBuyerout());
            } else {
                HisTradeExercisedetail tradeExercisedetail = iHisTradeExercisedetailMapper.selectOne(new QueryWrapper<HisTradeExercisedetail>()
                        .eq("tradeid", plan.getRelatedOrderId())
                        .eq("histradedate", histradedate));
                Goods goods = iGoodsMapper.selectOne(new QueryWrapper<Goods>().eq("goodsid", tradeExercisedetail.getGoodsid()));
                relatedInfoResult.setGoodsname(goods.getGoodsname());
                relatedInfoResult.setBuyerout(tradeExercisedetail.getBuyerout());
            }
            result.setRelatedInfoResult(relatedInfoResult);
        } else if (plan != null) {
            PayPerformanceReportResult reportResult;
            if (StringUtils.isEmpty(histradedate)) {
                reportResult = iPerformanceplanMapper.queryReportInfo(plan.getRelatedOrderId(), buyorsell);
            } else {
                reportResult = iPerformanceplanMapper.queryHisReportInfo(plan.getRelatedOrderId(), buyorsell, histradedate);
            }
            relatedInfoResult.setGoodsname(reportResult.getGoodsName());
            relatedInfoResult.setWrFactorTypeName(reportResult.getWrfactorTypeName());
            relatedInfoResult.setTradeAmount(reportResult.getTradeAmount());
            result.setRelatedInfoResult(relatedInfoResult);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
    }

    @Override
    public AjaxResult doBreach(PayPerformanceBreachParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        Performanceplan plan = iPerformanceplanMapper.selectOne(new QueryWrapper<Performanceplan>().eq("performanceplanid", param.getPerformanceplanid()));
        Long accountid = null;
        if (param.getSellorbuy() != null) {
            if (param.getSellorbuy() == 1) {
                accountid = plan.getBuyaccountid();
            } else if (param.getSellorbuy() == 2) {
                accountid = plan.getSellaccountid();
            }
            if (accountid != null && !iCommonService.checkTaaccountReport(systemmanager, accountid)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
            }
        }
        Performancebreachapply apply = iPerformancebreachapplyMapper.selectOne(new QueryWrapper<Performancebreachapply>()
                .eq("planid", param.getPerformanceplanid())
                .eq("breachstatus", 1));
        if (Objects.nonNull(apply)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM015.getCode(), request.getHeader("Accept-Language"));
        }

        PerformanceMI1.PerformanceContractedApplyReq.Builder builder = PerformanceMI1.PerformanceContractedApplyReq.newBuilder();
        Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
        Long uuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_Performance);
        hd.setUUID(uuid.toString());
        hd.setFunCode(FunCodeConstants.FunCode_Trade_PerformanceContractedApplyReq);
        hd.setClientTime(System.currentTimeMillis());
        builder.setHeader(hd);
        builder.setBreachType(param.getSellorbuy() == 1 ? 2 : 1);
        builder.setPerformancePlanID(param.getPerformanceplanid());
        builder.setApplyRemark(StringUtils.isBlank(param.getRemark()) ? "" : param.getRemark());
        builder.setAttachment(param.getAttachment());
        builder.setApplicant(systemmanager.getAreauserid());
        return sendPerformanceMsg(builder.build().toByteArray(),
                SysConstants.RabbitPerformanceNtfKey,
                FunCodeConstants.FunCode_Trade_PerformanceContractedApplyReq, uuid, request);
    }

    @Override
    public AjaxResult doDelay(PayPerformanceDelayParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        Performanceplan plan = iPerformanceplanMapper.selectOne(new QueryWrapper<Performanceplan>().eq("performanceplanid", param.getPerformanceplanid()));
        Long accountid = null;
        if (param.getSellorbuy() != null) {
            if (param.getSellorbuy() == 1) {
                accountid = plan.getBuyaccountid();
            } else if (param.getSellorbuy() == 2) {
                accountid = plan.getSellaccountid();
            }
            if (accountid != null && !iCommonService.checkTaaccountReport(systemmanager, accountid)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
            }
        }
        if (plan.getCurstepid().compareTo(param.getPerformanceplanid()) != 0) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM016.getCode(), request.getHeader("Accept-Language"));
        }

        PerformanceMI1.PerformanceDelayApplyReq.Builder builder = PerformanceMI1.PerformanceDelayApplyReq.newBuilder();
        Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
        hd.setFunCode(FunCodeConstants.FunCode_Trade_PerformanceDelayApplyReq);
        hd.setClientTime(System.currentTimeMillis());
        Long uuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_Performance);
        hd.setUUID(uuid.toString());
        builder.setHeader(hd);
        builder.setPerformancePlanStepID(param.getPerformancestepid());
        builder.setDelaydays(param.getDelaydays());
        builder.setApplyremark(StringUtils.isBlank(param.getRemark()) ? "" : param.getRemark());
        builder.setApplicant(systemmanager.getAreauserid());
        return sendPerformanceMsg(builder.build().toByteArray(),
                SysConstants.RabbitPerformanceNtfKey,
                FunCodeConstants.FunCode_Trade_PerformanceDelayApplyReq, uuid, request);
    }

    private AjaxResult sendPerformanceMsg(byte[] byteArray, String topic, Integer funcode, Long uuid, HttpServletRequest request) {
        byte[] body = ProtoHelper.getNTAS(byteArray, funcode);
        Calculator ca = new Calculator(uuid);
        SerialNumberUtils.lockMap.put(uuid, ca);
        rabbitTemplate.send(topic, new Message(body, new MessageProperties()));

        synchronized (ca) {
            try {
                ca.wait(10000);
                Object rsp = ca.obj;
                if (rsp != null) {
                    switch (funcode) {
                        //履约确认
                        case FunCodeConstants.FunCode_Trade_PerformanceManualConfirmReq: {
                            PerformanceMI1.PerformanceManualConfirmRsp rsp_ = (PerformanceMI1.PerformanceManualConfirmRsp) rsp;
                            if (rsp_.getRetCode() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM016.getCode(), request.getHeader("Accept-Language"));
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "", null);
                            }
                        }
                        //延期申请                                        FunCode_Trade_PerformanceDelayApplyReq
                        case FunCodeConstants.FunCode_Trade_PerformanceDelayApplyReq: {
                            PerformanceMI1.PerformanceDelayApplyRsp rsp_ = (PerformanceMI1.PerformanceDelayApplyRsp) rsp;
                            if (rsp_.getRetCode() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM017.getCode(), request.getHeader("Accept-Language"));
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "", null);
                            }
                        }
                        //违约申请                                        FunCode_Trade_PerformanceContractedApplyReq
                        case FunCodeConstants.FunCode_Trade_PerformanceContractedApplyReq: {
                            PerformanceMI1.PerformanceContractedApplyRsp rsp_ = (PerformanceMI1.PerformanceContractedApplyRsp) rsp;
                            if (rsp_.getRetCode() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM017.getCode(), request.getHeader("Accept-Language"));
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "", null);
                            }
                        }
                        //履约修改联络信息
                        case FunCodeConstants.FunCode_Trade_PerformanceModifyContactReq: {
                            PerformanceMI1.PerformanceModifyContactRsp rsp_ = (PerformanceMI1.PerformanceModifyContactRsp) rsp;
                            if (rsp_.getRetCode() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM018.getCode(), request.getHeader("Accept-Language"));
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "", null);
                            }
                        }
                        // 履约执行合同
                        case FunCodeConstants.FunCode_Trade_PerformanceExecuteContractReq: {
                            PerformanceMI1.PerformanceExecuteContractRsp rsp_ = (PerformanceMI1.PerformanceExecuteContractRsp) rsp;
                            if (rsp_.getRetCode() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM019.getCode(), request.getHeader("Accept-Language"));
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "", null);
                            }
                        }
                        // 履约激活
                        case FunCodeConstants.FunCode_Trade_PerformanceActivateReq: {
                            PerformanceMI1.PerformanceActivateRsp rsp_ = (PerformanceMI1.PerformanceActivateRsp) rsp;
                            if (rsp_.getRetCode() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM019.getCode(), request.getHeader("Accept-Language"));
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "", null);
                            }
                        }
                        default:
                            break;
                    }
                } else {
                    if (funcode == FunCodeConstants.FunCode_Trade_PerformanceModifyContactReq) {
                        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM018.getCode(), request.getHeader("Accept-Language"));
                    } else {
                        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM016.getCode(), request.getHeader("Accept-Language"));
                    }
                }
            } catch (InterruptedException e) {
                log.info("获取违约申请返回失败，失败原因：" + e.getMessage());
            } finally {
                SerialNumberUtils.lockMap.remove(uuid);
            }
        }

        return null;
    }
}
