package com.dxhy.erp.service.impl;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.api.model.config.sys.SysEnterpriseConfigDto;
import com.dxhy.common.constant.ConfigureConstant;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.ReturnCodeEnum;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.pojo.Authorize;
import com.dxhy.common.util.pojo.GlobalInfo;
import com.dxhy.erp.dao.AuthRecordDao;
import com.dxhy.erp.dao.RecordInvoiceDao;
import com.dxhy.erp.dao.SysEnterpriseConfigErpDao;
import com.dxhy.erp.dao.TdxRecordInvoiceErpDao;
import com.dxhy.erp.entity.AuthRecord;
import com.dxhy.erp.entity.RecordInvoice;
import com.dxhy.api.model.invoice.TDxRecordInvoice;
import com.dxhy.erp.model.AuthDateReq;
import com.dxhy.erp.model.AuthStatus;
import com.dxhy.erp.model.ReturnStateInfo;
import com.dxhy.erp.model.auth.InterfaceCode;
import com.dxhy.erp.service.InvoiceAuthService;
import com.dxhy.erp.utils.CheckUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author dxhy
 */
@SuppressWarnings({"AlibabaMethodTooLong", "AlibabaUndefineMagicConstant"})
@Service
@Slf4j
public class InvoiceAuthServiceImpl extends MpBaseServiceImpl<RecordInvoiceDao, RecordInvoice>
    implements InvoiceAuthService {

    @Autowired
    AuthRecordDao authRecordDao;
    @Autowired
    SysEnterpriseConfigErpDao enterpriseConfigErpDao;
    @Autowired
    TdxRecordInvoiceErpDao tDxrecordInvoiceDao;

    @Override
    public String applyInvoiceAuth(GlobalInfo globalInfo, Map<String, String> map, HttpServletRequest request,
        HttpServletResponse response, Authorize authorize) {
        ReturnStateInfo run = new ReturnStateInfo();
        InterfaceCode interfaceCode = new InterfaceCode();
        AuthDateReq data = null;
        try {
            data = JSONObject.parseObject(map.get("data"), AuthDateReq.class);
        } catch (Exception e) {
            run.setReturnCode(ReturnCodeEnum.QQBWGSCW.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.QQBWGSCW.getFhzMc(ReturnCodeEnum.QQBWGSCW.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }
        if (StringUtils.isBlank(data.getBatchNo()) || (!CheckUtils.stringLength(data.getBatchNo(), 32))) {
            run.setReturnCode(ReturnCodeEnum.PCHBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.PCHBNWK.getFhzMc(ReturnCodeEnum.PCHBNWK.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }
        if (StringUtils.isBlank(data.getApplyRzlx())) {
            run.setReturnCode(ReturnCodeEnum.RZLXBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.RZLXBNWK.getFhzMc(ReturnCodeEnum.RZLXBNWK.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }

        if ("4".equals(data.getApplyRzlx())) {
            if (StringUtils.isBlank(data.getBdklx())) {
                run.setReturnCode("9999");
                run.setReturnMessage("认证类型为不抵扣时，不抵扣类型不能为空");
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(run);
                return JSON.toJSONString(interfaceCode);
            } else {
                if ("5".equals(data.getBdklx()) && StringUtils.isBlank(data.getBdkyy())) {
                    if (StringUtils.isBlank(data.getBdkyy())) {
                        run.setReturnCode("9999");
                        run.setReturnMessage("认证类型为不抵扣时，不抵扣类型为5：其他时，不抵扣原因不能为空");
                        interfaceCode.setGlobalInfo(globalInfo);
                        interfaceCode.setReturnStateInfo(run);
                        return JSON.toJSONString(interfaceCode);
                    } else if (data.getBdkyy().length() > 30) {
                        run.setReturnCode("9999");
                        run.setReturnMessage("不抵扣原因长度不能超过30");
                        interfaceCode.setGlobalInfo(globalInfo);
                        interfaceCode.setReturnStateInfo(run);
                        return JSON.toJSONString(interfaceCode);
                    }
                }
            }
        }

        List<Map<String, Object>> authStateList = (List<Map<String, Object>>)data.getInvoices();
        run = getCheckData(authStateList, data.getContentRows());
        if (run.getReturnCode() != null || run.getReturnMessage() != null) {
            interfaceCode.setReturnStateInfo(run);
            interfaceCode.setGlobalInfo(globalInfo);
            return JSON.toJSONString(interfaceCode);
        }
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        SysEnterpriseConfigDto deptEntity = enterpriseConfigErpDao.getOrg(data.getBuyerTaxNo());
        String dbName = null;
        if (deptEntity != null && deptEntity.getDbName() != null) {
            dbName = deptEntity.getDbName();
        } else {
            ReturnStateInfo runInfo = new ReturnStateInfo();
            runInfo.setReturnCode(ReturnCodeEnum.JTSHBF.getFhzDm());
            runInfo.setReturnMessage(ReturnCodeEnum.JTSHBF.getFhzMc(ReturnCodeEnum.JTSHBF.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(runInfo);
            return JSON.toJSONString(interfaceCode);
        }

        DynamicContextHolder.push("business" + DbConstant.BUSINESS_READ);
        int resultNum = authRecordDao.selectCountRecord(data.getBatchNo(),data.getBuyerTaxNo(),ConfigureConstant.STRING_1);
        if (resultNum > 0) {
            ReturnStateInfo runInfo = new ReturnStateInfo();
            runInfo.setReturnCode("2099");
            runInfo.setReturnMessage("批次号已存在");
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(runInfo);
            return JSON.toJSONString(interfaceCode);
        }
        List<AuthRecord> authRecordList = bulidAuthRecord(authStateList, data.getBatchNo(), data.getApplyRzlx());
        // 申请认证记录保存
        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
        authRecordDao.insertAuthRecord(authRecordList, ConfigureConstant.STRING_1);
        if (StringUtils.isBlank(data.getApplyRzlx())) {
            data.setApplyRzlx("1");
        }
        for (Map<String, Object> authState : authStateList) {
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
            TDxRecordInvoice recordInvoice = tDxrecordInvoiceDao.getRecordInvoice((String)authState.get("buyerTaxNo"),
                (String)authState.get("invoiceCode"), (String)authState.get("invoiceNo"));
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
            if (recordInvoice != null) {
                if ("01".equals(recordInvoice.getInvoiceType())
                        || "03".equals(recordInvoice.getInvoiceType())
                        || "08".equals(recordInvoice.getInvoiceType())
                        || "14".equals(recordInvoice.getInvoiceType())
                        || "31".equals(recordInvoice.getInvoiceType())
                        || "185".equals(recordInvoice.getInvoiceType())
                        || "187".equals(recordInvoice.getInvoiceType())
                        || "161".equals(recordInvoice.getInvoiceType())
                        || "283".equals(recordInvoice.getInvoiceType())
                        || "383".equals(recordInvoice.getInvoiceType())
                ) {
                    if ("5".equals(data.getApplyRzlx())) {
                        if (!"4".equals(recordInvoice.getCxrzStatus()) && !"2".equals(recordInvoice.getCxrzStatus())
                            && !"1".equals(recordInvoice.getCxrzStatus())) {
                            String invoiceCode = StringUtils.isBlank((String)authState.get("invoiceCode"))?"":(String)authState.get("invoiceCode");
                            tDxrecordInvoiceDao.updateCxrz((String)authState.get("applyTaxPeriod"),
                                    invoiceCode+ (String)authState.get("invoiceNo"));
                        }
                    } else if ("6".equals(data.getApplyRzlx())) {
                        if (!"4".equals(recordInvoice.getCxbdkStatus()) && !"2".equals(recordInvoice.getCxbdkStatus())
                            && !"1".equals(recordInvoice.getCxrzStatus())) {
                            String invoiceCode = StringUtils.isBlank((String)authState.get("invoiceCode"))?"":(String)authState.get("invoiceCode");
                            tDxrecordInvoiceDao.updateCxbdk((String)authState.get("applyTaxPeriod"),
                                    invoiceCode + (String)authState.get("invoiceNo"));
                        }
                    } else {
                        if (!"4".equals(recordInvoice.getAuthStatus()) && !"3".equals(recordInvoice.getAuthStatus())
                            && !"2".equals(recordInvoice.getAuthStatus())) {
                            if ("1".equals(data.getApplyRzlx())) {
                                tDxrecordInvoiceDao.updateRz(authState, data.getApplyRzlx(), "1",
                                    recordInvoice.getUuid());
                            } else if ("4".equals(data.getApplyRzlx())) {
                                tDxrecordInvoiceDao.updateRzBdk(authState, data.getApplyRzlx(), "2",data.getBdklx(),data.getBdkyy(),
                                    recordInvoice.getUuid());
                            } else if ("2".equals(data.getApplyRzlx())) {
                                //退税
                                tDxrecordInvoiceDao.updateRz(authState, data.getApplyRzlx(), "3",
                                        recordInvoice.getUuid());
                            }else {
                                tDxrecordInvoiceDao.updateRz(authState, data.getApplyRzlx(), "99",
                                    recordInvoice.getUuid());
                            }
                        }
                    }
                }else{
                    log.info("票种属于不可认证票种:{}",recordInvoice.getInvoiceType());
                }
            }
        }
        if (run.getReturnCode() == null) {
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
        }
        interfaceCode.setReturnStateInfo(run);
        interfaceCode.setGlobalInfo(globalInfo);
        return JSON.toJSONString(interfaceCode);
    }

    public List<AuthRecord> bulidAuthRecord(List<Map<String, Object>> list, String batchNo, String rzlx) {
        List<AuthRecord> authRecordList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            AuthRecord authRecord = new AuthRecord();
            authRecord.setBatchNo(batchNo);
            authRecord.setInvoiceCode((String)map.get("invoiceCode"));
            authRecord.setInvoiceNo((String)map.get("invoiceNo"));
            authRecord.setUuid(map.get("invoiceCode") + (String)map.get("invoiceNo"));
            if (StringUtils.isBlank(rzlx)) {
                authRecord.setRzlx("1");
            } else {
                authRecord.setRzlx(rzlx);
            }
            authRecord.setApplyTaxPeriod((String)map.get("applyTaxPeriod"));
            authRecord.setBuyerTaxNo((String)map.get("buyerTaxNo"));
            authRecord.setYxse((String)map.get("taxCredit"));
            authRecord.setCreateDate(new Date());
            authRecordList.add(authRecord);
        }
        return authRecordList;
    }

    @Override
    public String getAuthResult(GlobalInfo globalInfo, Map<String, String> map, HttpServletRequest request,
        HttpServletResponse response, Authorize authorize) {
        ReturnStateInfo run = new ReturnStateInfo();
        InterfaceCode interfaceCode = new InterfaceCode();
        AuthDateReq data = null;
        try {
            data = JSONObject.parseObject(map.get("data"), AuthDateReq.class);
        } catch (Exception e) {
            run.setReturnCode(ReturnCodeEnum.QQBWGSCW.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.QQBWGSCW.getFhzMc(ReturnCodeEnum.QQBWGSCW.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }
        if (StringUtils.isBlank(data.getBatchNo()) || (!CheckUtils.stringLength(data.getBatchNo(), 32))) {
            run.setReturnCode(ReturnCodeEnum.PCHBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.PCHBNWK.getFhzMc(ReturnCodeEnum.PCHBNWK.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }
        if (StringUtils.isBlank(data.getBuyerTaxNo())) {
            run.setReturnCode(ReturnCodeEnum.SHBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.SHBNWK.getFhzMc(ReturnCodeEnum.SHBNWK.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        SysEnterpriseConfigDto deptEntity = enterpriseConfigErpDao.getOrg(data.getBuyerTaxNo());
        String dbName = null;
        if (deptEntity != null && deptEntity.getDbName() != null) {
            dbName = deptEntity.getDbName();
        } else {
            ReturnStateInfo runInfo = new ReturnStateInfo();
            runInfo.setReturnCode(ReturnCodeEnum.JTSHBF.getFhzDm());
            runInfo.setReturnMessage(ReturnCodeEnum.JTSHBF.getFhzMc(ReturnCodeEnum.JTSHBF.getIndex()));
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(runInfo);
            return JSON.toJSONString(interfaceCode);
        }
        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
        int resultNum = authRecordDao.selectCountRecord(data.getBatchNo(),data.getBuyerTaxNo(),ConfigureConstant.STRING_1);
        List<AuthStatus> authStatuses = tDxrecordInvoiceDao.selectAuthResult(data.getBatchNo());
        boolean r = authStatuses != null && authStatuses.size() > 0;
        if (resultNum == 0 || r) {
            data.setContentRows(0);
            data.setBatchState("N");
            String resultData = JSON.toJSONString(data);
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
            interfaceCode.setReturnStateInfo(run);
            interfaceCode.setGlobalInfo(globalInfo);

            interfaceCode.setData(Base64.encode(resultData));

            return JSON.toJSONString(interfaceCode);
        }
        List<AuthStatus> authStatusList = tDxrecordInvoiceDao.selectAuthResultBack(data.getBatchNo());
        DecimalFormat df = new DecimalFormat("#0.00");
        for (AuthStatus authStatus : authStatusList) {
            if ("0".equals(authStatus.getAuthState())) {
                authStatus.setFailureReason("未认证");
            }
            if (authStatus.getAuthState() == null) {
                authStatus.setAuthState("5");
                authStatus.setLegalizeState("0");
                authStatus.setFailureReason("无此底账");
            }
            if (authStatus.getLegalizeDate() == null) {
                authStatus.setLegalizeDate("");
            }
            if (authStatus.getFailureReason() == null) {
                authStatus.setFailureReason("");
            }
            if (authStatus.getLegalizeBelongDate() == null) {
                authStatus.setLegalizeBelongDate("");
            }
            if (authStatus.getManagementStatus() == null) {
                authStatus.setManagementStatus("");
            }
            if (authStatus.getInformationSources() == null) {
                authStatus.setInformationSources("");
            }
            if (authStatus.getOverdueCheckMark() == null) {
                authStatus.setOverdueCheckMark("");
            }
            if ("1".equals(authStatus.getRzlx()) || "4".equals(authStatus.getRzlx())) {
                if (StringUtils.isNotBlank(authStatus.getTaxCredit())) {
                    authStatus.setTaxCredit(df.format(new BigDecimal(authStatus.getTaxCredit())));
                } else {
                    authStatus.setTaxCredit("");
                }
            } else {
                authStatus.setTaxCredit("");
            }
            if("5".equals(authStatus.getRzlx())){
                authStatus.setAuthState(authStatus.getCxrzStatus());
            }
            if(StringUtils.isBlank(authStatus.getInvoiceCode())){
                authStatus.setInvoiceCode("");
            }

            if("6".equals(authStatus.getRzlx())){
                authStatus.setAuthState(authStatus.getCxbdkStatus());
            }
            if("0".equals(authStatus.getRzlx())){
                authStatus.setAuthState("0");
            }
        }
        data.setBatchState("Y");
        data.setContentRows(authStatusList.size());
        data.setInvoices(authStatusList);
        String resultData = JSON.toJSONString(data);
        run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
        run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
        interfaceCode.setReturnStateInfo(run);
        interfaceCode.setGlobalInfo(globalInfo);

        interfaceCode.setData(Base64.encode(resultData));

        return JSON.toJSONString(interfaceCode);
    }

    public ReturnStateInfo getCheckData(List<Map<String, Object>> authStateList, Integer contentRows) {
        ReturnStateInfo run = new ReturnStateInfo();
        if (contentRows == null || authStateList.size() != contentRows) {
            run.setReturnCode(ReturnCodeEnum.NRYCY.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.NRYCY.getFhzMc(ReturnCodeEnum.NRYCY.getIndex()));
            return run;
        }

        for (Map<String, Object> map : authStateList) {
//            if (StringUtils.isBlank((String)map.get("invoiceCode")) || StringUtils.isBlank((String)map.get("invoiceNo"))
//                || ((String)map.get("invoiceCode")).length() > 12 || ((String)map.get("invoiceNo")).length() > 10) {
//                run.setReturnCode(ReturnCodeEnum.DMHMBF.getFhzDm());
//                run.setReturnMessage(ReturnCodeEnum.DMHMBF.getFhzMc(ReturnCodeEnum.DMHMBF.getIndex()));
//                return run;
//            }
            boolean r =
                    !(CheckUtils.stringLength((String)map.get("invoiceNo"), 8) || CheckUtils.stringLength((String)map.get("invoiceNo"), 10)
                    || CheckUtils.stringLength((String)map.get("invoiceNo"), 18) || CheckUtils.stringLength((String)map.get("invoiceNo"), 20));
            if (CheckUtils.isNullOrEmpty((String)map.get("invoiceNo")) || r) {
                run.setReturnCode(ReturnCodeEnum.DMHMBF.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.DMHMBF.getFhzMc(ReturnCodeEnum.DMHMBF.getIndex()));
            }
            if (StringUtils.isBlank((String)map.get("applyTaxPeriod"))
                || ((String)map.get("applyTaxPeriod")).length() != 6) {
                run.setReturnCode(ReturnCodeEnum.SKSSQBF.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.SKSSQBF.getFhzMc(ReturnCodeEnum.SKSSQBF.getIndex()));
                return run;
            }
            if (StringUtils.isBlank((String)map.get("buyerTaxNo"))) {
                run.setReturnCode(ReturnCodeEnum.SHBNWK.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.SHBNWK.getFhzMc(ReturnCodeEnum.SHBNWK.getIndex()));
                return run;
            }
            if (StringUtils.isBlank((String)map.get("rz_user"))) {
                run.setReturnCode(ReturnCodeEnum.RZRBNWK.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.RZRBNWK.getFhzMc(ReturnCodeEnum.RZRBNWK.getIndex()));
                return run;
            }

//            if (StringUtils.isBlank((String)map.get("taxCredit"))) {
//                run.setReturnCode(ReturnCodeEnum.DKSEBNWK.getFhzDm());
//                run.setReturnMessage(ReturnCodeEnum.DKSEBNWK.getFhzMc(ReturnCodeEnum.DKSEBNWK.getIndex()));
//                return run;
//            }
        }
        return run;
    }

}
