package com.brilliance.isc.swift.swtmsg;

import com.brilliance.isc.annotation.BeforeSwift;
import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Pty;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.doc.TextResultVo;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.setmod.vo.SetmodVo;
import com.brilliance.isc.common.trndoc.vo.DoceotVo;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.mda.dao.PtyMapper;
import com.brilliance.isc.swift.objmtconvert.manager.MtCreatorManager;
import com.brilliance.isc.swift.objmtconvert.model.commontag.ActnoBicAdrTagXXX;
import com.brilliance.isc.swift.objmtconvert.model.commontag.DcDateCurAmtTagXXX;
import com.brilliance.isc.swift.objmtconvert.model.mt2xx.MT202Creator;
import com.brilliance.isc.swift.objmtconvert.model.mt4xx.MT400Creator;
import com.brilliance.isc.swift.objmtconvert.model.mt7xx.MT756Creator;
import com.brilliance.isc.swift.objmtconvert.result.MtResult;
import com.brilliance.isc.swift.swtmsg.vo.Swt202Request;
import com.brilliance.isc.swift.swtmsg.vo.Swt400Request;
import com.brilliance.isc.swift.swtmsg.vo.Swt756Request;
import com.brilliance.isc.vo.FxpmodVo;
import com.brilliance.isc.vo.model.SetgrpVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

//2期公共报文组报类 例如756 400 202
@Component
public class SwtBuilder {

    @Autowired
    private SwiftMessageComponent swiftMessageComponent;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private CodetableService codetableService;

    @Resource
    private PtyMapper ptyMapper;

    private static final String CR = "\n";

    @BeforeSwift
    public TextResultVo buildMt756(Swt756Request swt756Request, SetgrpVo setgrpVo) {
        SetmodVo setmodVo = swt756Request.getSetmodVo();
        DoceotVo doceotVo = swt756Request.getDoceotVo();
        Object xxxgrp = swt756Request.getXxxgrp();
        SetgllVo setgllVo = swt756Request.getSetgllVo();
        MT756Creator mt756Creator = new MT756Creator();
        //收报行bic
        mt756Creator.setRecvBic(doceotVo.getAdrbic());
        //发报行bic
        mt756Creator.setSendBic(getSendBic());
        //20
        mt756Creator.setSendersReference(swiftMessageComponent.swtPrtReference(xxxgrp));
        //21
        PtsptaVo snd756 = setgllVo.getSetgrp().getSnd756();
        if (StringUtils.isNotEmpty(snd756.getPts().getRef())) {
            mt756Creator.setPresentingBanksReference(snd756.getPts().getRef());
        } else {
            mt756Creator.setPresentingBanksReference("NONREF");
        }
        //32B
        DcDateCurAmtTagXXX totalAmountClaimed = new DcDateCurAmtTagXXX("32", "756");
        totalAmountClaimed.setAmount(setmodVo.getDocamt());
        totalAmountClaimed.setCurrency(setmodVo.getDoccur());
        mt756Creator.setTotalAmountClaimed(totalAmountClaimed);
        //33
        String acccur = setgllVo.getAcccur();
        BigDecimal accamt = setgllVo.getAccamt();
        if (BigDecimal.ZERO.compareTo(accamt) != 0) {
            if (StringUtils.isNotEmpty(acccur)) {
                if (setgllVo.getValdat() != null) {
                    DcDateCurAmtTagXXX amountReimbursedOrPaid = new DcDateCurAmtTagXXX("33", "");
                    amountReimbursedOrPaid.setCurrency(acccur);
                    amountReimbursedOrPaid.setAmount(accamt.abs());
                    amountReimbursedOrPaid.setDate(printSwiftDate(setgllVo.getValdat()));
                    mt756Creator.setAmountReimbursedOrPaid(amountReimbursedOrPaid);
                }
            }
        }
        //53
        ActnoBicAdrTagXXX sendersCorrespondent = swiftMessageComponent.swtPrtAccAdrSpc("53", "756", setgrpVo.getActser(), setgllVo.getActrec().getSeracc(), "");
        mt756Creator.setSendersCorrespondent(sendersCorrespondent);
        //54
        ActnoBicAdrTagXXX receiversCorrespondent = swiftMessageComponent.swtPrtAccAdrSpc("54", "756", setgrpVo.getRcvcor2(), setgllVo.getSespay().getRcvcor2acc(), "");
        mt756Creator.setReceiversCorrespondent(receiversCorrespondent);
        //72Z
        mt756Creator.setSendertoReceiverInformation(StringUtils.convertBlock(setgllVo.getSespay().getStrinf(), 6, 35));
        //79Z
        mt756Creator.setNarrative(StringUtils.convertBlock(doceotVo.getTag79z(), 35, 50));
        MtResult mtResult = MtCreatorManager.packMT(mt756Creator);
        return buildTextVo(mtResult);
    }

    @BeforeSwift
    public TextResultVo buildMt202(Swt202Request swt202Request, SetgrpVo setgrpVo) {
        DoceotVo doceotVo = swt202Request.getDoceotVo();
        SetgllVo setgllVo = swt202Request.getSetgllVo();
        MT202Creator mt202Creator = new MT202Creator();
        //收报行bic
        mt202Creator.setRecvBic(doceotVo.getAdrbic());
        //发报行bic
        mt202Creator.setSendBic(getSendBic());
        //20
        mt202Creator.setTransactionReferenceNumber(setgllVo.getSespay().getOwnref());
        //21
        String relatedReference = "";
        if (ptsptaToolComponent.ptsIsRolSet(setgrpVo.getBei())) {
            relatedReference = setgrpVo.getBei().getRef();
        }
        if (StringUtils.isEmpty(relatedReference)) {
            PtsptaVo prbPtspta = Utils.getFieldValue(swt202Request.getXxxgrp(), "prb");
            if (prbPtspta != null) {
                relatedReference = prbPtspta.getRef();
            }
        }
        if (StringUtils.isEmpty(relatedReference)) {
            PtsptaVo rolePtspta = Utils.getFieldValue(swt202Request.getXxxgrp(), setgllVo.getRol());
            if (rolePtspta != null) {
                relatedReference = rolePtspta.getRef();
            }
        }
        if (StringUtils.isEmpty(relatedReference)) {
            relatedReference = "NONREF";
        }
        mt202Creator.setRelatedReference(relatedReference);
        //32
        DcDateCurAmtTagXXX valueDateCurrencyAmount = new DcDateCurAmtTagXXX("32");
        valueDateCurrencyAmount.setCurrency(setgllVo.getAcccur());
        valueDateCurrencyAmount.setAmount(setgllVo.getAccamt().abs());
        valueDateCurrencyAmount.setDate(printSwiftDate(setgllVo.getValdat()));
        mt202Creator.setValueDateCurrencyAmount(valueDateCurrencyAmount);
        //52A
        ActnoBicAdrTagXXX actnoBicAdr52a = swiftMessageComponent.swtPrtExtAccAdrAD("52", setgrpVo.getOri(), "");
        mt202Creator.setOrderingInstitution(actnoBicAdr52a);
        if (ptsptaToolComponent.ptsIsRolSet(setgrpVo.getTri())) {
            //56
            ActnoBicAdrTagXXX intermediary = swiftMessageComponent.swtPrtAccAdrSpc("56", "202", setgrpVo.getRcvcor(), setgllVo.getSespay().getRcvcoracc(), "");
            mt202Creator.setIntermediary(intermediary);
        }
        if (ptsptaToolComponent.ptsIsRolSet(setgrpVo.getTri())) {
            //57
            ActnoBicAdrTagXXX accountWithInstitution = swiftMessageComponent.swtPrtAccAdrSpc("57", "202", setgrpVo.getTri(), setgllVo.getSespay().getTriacc(), "");
            mt202Creator.setAccountWithInstitution(accountWithInstitution);
        } else {
            //57
            ActnoBicAdrTagXXX accountWithInstitution = swiftMessageComponent.swtPrtAccAdrSpc("57", "202", setgrpVo.getRcvcor(), setgllVo.getSespay().getRcvcoracc(), "");
            mt202Creator.setAccountWithInstitution(accountWithInstitution);
        }
        //58
        ActnoBicAdrTagXXX beneficiaryInstitution = swiftMessageComponent.swtPrtTag58Spc("202", setgrpVo.getBei(), setgllVo.getSespay().getBeiacc(), doceotVo, swt202Request.getSetglgVo());
        mt202Creator.setBeneficiaryInstitution(beneficiaryInstitution);
        //72
        mt202Creator.setSenderToReceiverInformation(StringUtils.convertBlock(setgllVo.getSespay().getStrinf202(), 6, 35));

        MtResult mtResult = MtCreatorManager.packMT(mt202Creator);
        return buildTextVo(mtResult);
    }

    @BeforeSwift
    public TextResultVo buildMt400(Swt400Request swt400Request, SetgrpVo setgrpVo) {
        SetmodVo setmodVo = swt400Request.getSetmodVo();
        DoceotVo doceotVo = swt400Request.getDoceotVo();
        Object xxxgrp = swt400Request.getXxxgrp();
        SetgllVo setgllVo = swt400Request.getSetgllVo();
        MT400Creator mt400Creator = new MT400Creator();
        //收报行bic
        mt400Creator.setRecvBic(doceotVo.getAdrbic());
        //发报行bic
        mt400Creator.setSendBic(getSendBic());
        //20
        mt400Creator.setSendingBankTRN(swiftMessageComponent.swtPrtReference(xxxgrp));
        //21
        PtsptaVo snd756 = setgllVo.getSetgrp().getSnd756();
        if (StringUtils.isNotEmpty(snd756.getRef())) {
            mt400Creator.setRelatedReference(snd756.getRef());
        } else {
            mt400Creator.setRelatedReference("NONREF");
        }
        //32B
        DcDateCurAmtTagXXX amountCollected = new DcDateCurAmtTagXXX("32");
        amountCollected.setAmount(setmodVo.getDocamt());
        amountCollected.setCurrency(setmodVo.getDoccur());
        mt400Creator.setAmountCollected(amountCollected);
        //33
        String acccur = setgllVo.getAcccur();
        BigDecimal accamt = setgllVo.getAccamt();
        if (BigDecimal.ZERO.compareTo(accamt) != 0) {
            if (StringUtils.isNotEmpty(acccur)) {
                if (setgllVo.getValdat() != null) {
                    DcDateCurAmtTagXXX proceedsRemitted = new DcDateCurAmtTagXXX("33");
                    proceedsRemitted.setCurrency(acccur);
                    proceedsRemitted.setAmount(accamt.abs());
                    proceedsRemitted.setDate(printSwiftDate(setgllVo.getValdat()));
                    mt400Creator.setProceedsRemitted(proceedsRemitted);
                }
            }
        }
        //52
        //53
        ActnoBicAdrTagXXX senderCorrespondent = swiftMessageComponent.swtPrtAccAdrSpc("53", "400", setgrpVo.getActser(), setgllVo.getActrec().getSeracc(), "");
        mt400Creator.setSenderCorrespondent(senderCorrespondent);
        //54
        ActnoBicAdrTagXXX receiverCorrespondent = swiftMessageComponent.swtPrtAccAdrSpc("54", "400", setgrpVo.getRcvcor2(), setgllVo.getSespay().getRcvcoracc(), "");
        mt400Creator.setReceiverCorrespondent(receiverCorrespondent);
        //57
        ActnoBicAdrTagXXX accountWithBank = swiftMessageComponent.swtPrtAccAdrSpc("57", "400", setgrpVo.getAwi(), setgllVo.getSespay().getAwiacc(), "");
        mt400Creator.setAccountWithBank(accountWithBank);
        //58
        ActnoBicAdrTagXXX beneficiaryBank = swiftMessageComponent.swtPrtAccAdrSpc("58", "400", setgrpVo.getBei(), setgllVo.getSespay().getBeiacc(), "");
        mt400Creator.setBeneficiaryBank(beneficiaryBank);
        //71B
        String detailsOfCharges = swiftMessageComponent.printSwiftFeeDetDspFun(setmodVo, setgllVo.getRol(), "71B", "X", "", "" );
        if (StringUtils.isNotEmpty(detailsOfCharges)) {
            mt400Creator.setDetailsOfCharges(detailsOfCharges);
        }
        //72Z
        mt400Creator.setSenderToReceiverInformation(StringUtils.convertBlock(setgllVo.getSespay().getStrinf(), 6, 35));
        MtResult mtResult = MtCreatorManager.packMT(mt400Creator);
        return buildTextVo(mtResult);
    }

    public TextResultVo buildFxps(FxpmodVo fxpmod) {
        Map<String, String> map = new LinkedHashMap<>();
        //报文头
        Map<String, String> msgHead = new LinkedHashMap<>();
        msgHead.put(":FXPS:", fxpmod.getFmttyp());
        String ioVal = "";
        if (StringUtils.isNotEmpty(fxpmod.getResbch())) {
            Pty pty = ptyMapper.selectByExtkey(fxpmod.getResbch());
            if (pty != null) {
                PtsptaVo resPtsptaVo = ptsptaToolComponent.getPtsptaFromPtyINR(pty.getInr());
                ptsptaToolComponent.fillPtsptaAllProperties(resPtsptaVo);
                ioVal = fxpmod.getResbch()+ " identified as: " + CR + resPtsptaVo.getAdrblk();
            } else {
                ioVal = fxpmod.getResbch()+ " identified as: " + CR + "";
            }
            msgHead.put(":IO:", ioVal);
        }
        if (StringUtils.isNotEmpty(fxpmod.getSndbch())) {
            Pty pty = ptyMapper.selectByExtkey(fxpmod.getSndbch());
            String iiVal = "";
            if (pty != null) {
                PtsptaVo sndPtsptaVo = ptsptaToolComponent.getPtsptaFromPtyINR(pty.getInr());
                ptsptaToolComponent.fillPtsptaAllProperties(sndPtsptaVo);
                iiVal = fxpmod.getSndbch()+ " identified as: " + CR + sndPtsptaVo.getAdrblk();
            } else {
                iiVal = fxpmod.getSndbch()+ " identified as: " + CR + "";
            }
            msgHead.put(":II:", iiVal);
        }
        map.putAll(msgHead);
        //报文体
        Map<String, String> msgBody = new LinkedHashMap<>();
        if ("111".equalsIgnoreCase(fxpmod.getFmttyp())) {
            msgBody.put(":23B:", "CRED");
        } else {
            msgBody.put(":21:", fxpmod.getRelatedref());
        }
        BigDecimal amt = fxpmod.getAmt();
        if (amt != null) {
            BigDecimal amtScale = amt.setScale(2, RoundingMode.HALF_UP);
            msgBody.put(":32A:", fxpmod.getCur()+amtScale);
        } else {
            msgBody.put(":32A:", fxpmod.getCur()+fxpmod.getAmt());
        }
        String value50 = this.getActNamAdrForA52A56(fxpmod.getOrcact(), "/A52/", "/A53/", fxpmod.getOrcnam(), fxpmod.getOrcadr());
        if (StringUtils.isNotEmpty(value50)) {
            msgBody.put(":50K:", value50);
        }
        String value52 = "";
        if (StringUtils.isNotEmpty(fxpmod.getSbkact())) {
            value52 += "/" + fxpmod.getSbkact();
        }
        if (ptsptaToolComponent.ptsIsRolSet(fxpmod.getOri())) {
            ptsptaToolComponent.fillPtsptaAllProperties(fxpmod.getOri());
            if (StringUtils.isNotEmpty(value52)) {
                value52 += CR + fxpmod.getOri().getAdr().getBic() + CR + fxpmod.getOri().getAdrblk();
            } else {
                value52 += fxpmod.getOri().getAdr().getBic() + CR + fxpmod.getOri().getAdrblk();
            }
        }
        if (StringUtils.isNotEmpty(value52)) {
            msgBody.put(":52D:", value52);
        }
        //发起和接收清算行行号，光大可能不需要
        //msgBody.put(":53A:", );
        //msgBody.put(":54A:", );
        msgBody.put(":56A:", ioVal);
        String value57 = "";
        if (StringUtils.isNotEmpty(fxpmod.getRbkact())) {
            value57 += "/" + fxpmod.getRbkact();
        }
        if (ptsptaToolComponent.ptsIsRolSet(fxpmod.getPyb())) {
            ptsptaToolComponent.fillPtsptaAllProperties(fxpmod.getPyb());
            if (StringUtils.isNotEmpty(value57)) {
                value57 += CR + fxpmod.getPyb().getAdr().getBic() + CR + fxpmod.getPyb().getAdrblk();
            } else {
                value57 += fxpmod.getPyb().getAdr().getBic() + CR + fxpmod.getPyb().getAdrblk();
            }
        }
        if (StringUtils.isNotEmpty(value57)) {
            msgBody.put(":57D:", value57);
        }
        String value59 = this.getActNamAdrForA52A56(fxpmod.getPyeact(), "/A55/", "/A56/", fxpmod.getPyenam(), fxpmod.getPyeadr());
        if (StringUtils.isNotEmpty(value59)) {
            msgBody.put(":59:", value59);
        }
        if (StringUtils.isNotEmpty(fxpmod.getCommet())) {
            msgBody.put(":70:", fxpmod.getCommet());
        }
        if (StringUtils.isNotEmpty(fxpmod.getFeetyp()) && "111".equalsIgnoreCase(fxpmod.getFmttyp())) {
            msgBody.put(":71A:", fxpmod.getFeetyp());
        }
        String value72 = "";
        if (fxpmod.getValdat() != null) {
            value72 += "/B00/" + Utils.fmtDate(fxpmod.getValdat(), "yyyyMMdd") + CR;
        }
        Bch bch = SettleContext.getUserSession().getBch();
        if (bch != null) {
            value72 += "/A30/" + bch.getSwfcod() + CR;
        }
        if (StringUtils.isNotEmpty(fxpmod.getTxntyp())) {
            String label = codetableService.getTblLabel(fxpmod.getTxntyp(), "YWLXDM", "CN");
            value72 += "/E25/" + fxpmod.getTxntyp() + label + CR;
        }
        if (StringUtils.isNotEmpty(fxpmod.getBustyp())) {
            String label = codetableService.getTblLabel(fxpmod.getBustyp(), "HBSTYP", "CN");
            value72 += "/E26/" + fxpmod.getBustyp() + label + CR;
        }
        if (StringUtils.isNotEmpty(fxpmod.getAcctyp())) {
            String label = codetableService.getTblLabel(fxpmod.getAcctyp(), "ACTPRO", "CN");
            value72 += "/G53/" + fxpmod.getAcctyp() + label;
        } else {
            value72 += "/G53/";
        }
        if (StringUtils.isNotEmpty(value72)) {
            msgBody.put(":72:", value72);
        }
        map.putAll(msgBody);
        //以换行符合并字符串
        String messageText = map.entrySet().stream().reduce(new StringBuilder(),(accsb,item)->{
            accsb.append(item.getKey());
            accsb.append(item.getValue());
            accsb.append(CR);
            return accsb;
        },(a,b)->a.append(b)).toString().trim();
        TextResultVo textResultVo = new TextResultVo();
        textResultVo.setData(messageText);
        textResultVo.setFormat("fmt");
        textResultVo.setExtension("txt");
        textResultVo.setBinary(messageText.getBytes());
        return textResultVo;
    }

    private TextResultVo buildTextVo(MtResult mtResult) {
        if (mtResult != null) {
            TextResultVo textResultVo = new TextResultVo();
            textResultVo.setData(mtResult.getMessage());
            textResultVo.setFormat("text");
            textResultVo.setExtension("sf2");
            textResultVo.setBinary(mtResult.getMessage().getBytes());
            textResultVo.setAttach(mtResult.getAbsMTCreator());
            return textResultVo;
        }
        return null;
    }

    private String getSendBic() {
        String bicCode = "";
        Bch bch = SettleContext.getUserSession().getBch();
        if (bch != null) {
            bicCode = bch.getSwfcod();
        } else {
            bicCode = SettleContext.getUserSession().getWrkbch().getSwfcod();
        }

        return bicCode;
    }

    private String printSwiftDate(Date date) {
        return date != null ? Utils.fmtDate(date, "yyMMdd") : null;
    }

    private String getActNamAdrForA52A56(String act, String namTag, String adrTag, String nam, String adr) {
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotEmpty(act)) {
            sb.append("/" + act);
        }
        if (StringUtils.isNotEmpty(nam)) {
            if (sb.length() > 0) {
                sb.append("\n");
            }
            sb.append(namTag + nam);
        }
        if (StringUtils.isNotEmpty(adr)) {
            if (sb.length() > 0) {
                sb.append(CR);
            }
            sb.append(adrTag + adr);
        }
        return sb.toString();
    }

}
