package com.dxhy.erp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.*;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.common.vo.UserInfo;
import com.dxhy.erp.dao.CheckLogDao;
import com.dxhy.erp.entity.ExtSmcyVO;
import com.dxhy.erp.entity.TDxCheckLog;
import com.dxhy.erp.entity.TdxCheckRecordInvoice;
import com.dxhy.erp.service.InvoiceQueryService;
import com.dxhy.erp.service.SignCheckRecordService;
import com.dxhy.erp.service.SignSaveCheckInfoService;
import com.dxhy.erp.utils.InvoiceQueryUtil;
import com.dxhy.ofd.service.OfdService;
import com.dxhy.oss.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author ld
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong", "AlibabaStringConcat",
    "AlibabaAvoidComplexCondition", "AlibabaCollectionInitShouldAssignCapacity"})
@Service("invoiceQueryService")
@Slf4j
public class InvoiceQueryServiceImpl extends MpBaseServiceImpl<CheckLogDao, TDxCheckLog>
    implements InvoiceQueryService {

    @Resource
    private InvoiceQueryUtil invoiceQueryUtil;
    @Resource
    private OfdService ofdService;
    @Resource
    private ScanIdUtils scanIdUtils;

    @Resource
    private SignCheckRecordService signCheckRecordService;

    @Resource
    private SignSaveCheckInfoService signSaveCheckInfoService;

    @Resource
    private TabulateRedisService tabulateRedisService;
    @Resource
    private FileService fileService;
    /**
     * 只允许查验成功一次公司编码
     */

    @Value("${checkCount.company}")
    private String companyCheck;


    @Override
    public String smQueryInvoice(Map<String, String> pramsMap) {

        String[] titlelist = {"查验结果描述", "发票代码", "发票号码", "开票日期", "发票金额", "校验码"};
        String[] titleprop =
                {"checkMassege", "invoiceCode", "invoiceNo", "invoiceDate", "invoiceAmount", "checkCode", "invoiceType"};
        // 需要设置返回列表标题时调用
        JSONObject json = super.setTitleList(titlelist, titleprop);

        TDxCheckLog checkLog = this.checkSingleInvioce(pramsMap);

        List<ExtSmcyVO> returnList = new ArrayList<>();
        ExtSmcyVO smcyVo = this.convertToSmcyView(checkLog);
        returnList.add(smcyVo);

        json.put("datalist", returnList);

        return super.responseResult(json);
    }

    @Override
    public String checkingInvoiceInfo(String dbName, String uuid, UserInfo userInfo) {
        String notes = null;
        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
        TdxCheckRecordInvoice checkRecordTmp = signCheckRecordService.getCheckInvoiceByUuid(uuid);
        if (checkRecordTmp != null) {
            if (!StringUtils.isBlank(checkRecordTmp.getCheckUser()) && userInfo != null
                    && !userInfo.getUsername().equals(checkRecordTmp.getCheckUser())) {
                notes = "该发票票已被他人查验，不可重复查验！";
                return notes;
            }
            if ("0001".equals(checkRecordTmp.getCyjgCode())) {
                if (companyCheck.contains(userInfo.getCompany())) {
                    notes = "该发票已查验成功，不可重复查验！";
                    return notes;
                } else if (DateUtils.getStringDateShort().equals(DateUtils.dateToStr(checkRecordTmp.getCreateDate()))) {
                    notes = "该发票今日已查验成功，不可重复查验！";
                }
            }
        }
        return notes;
    }

    /**
     * 查验一张发票信息，此方法为公共方法，多种查验方式公用
     *
     * @param pramsMap
     *            请求参数
     * @return 返回结果
     *
     */
    private TDxCheckLog checkSingleInvioce(Map<String, String> pramsMap) {

        TDxCheckLog checkLog = new TDxCheckLog();

        String userId = pramsMap.get("userid");
        String invoiceType = pramsMap.get("invoiceType");
        String invoiceCode = pramsMap.get("invoiceCode");
        if (StringHelper.isBlank(invoiceType)) {
            if(FplxEnum.QDZZP.getFplxDm().equals(invoiceType) || FplxEnum.QDPP.getFplxDm().equals(invoiceType)){
                invoiceType = "31";
            }else {
                InvoiceUtil iu = new InvoiceUtil(invoiceCode);
                invoiceType = iu.getFplxdm();
            }
        }

        // 通行费发票二维码中的发票类型代码为10“电子发票”，需要单独根据发票代码判断发票类型
        if (FplxEnum.DZP.getFplxDm().equals(invoiceType)) {
            InvoiceUtil iu = new InvoiceUtil(invoiceCode);
            if (FplxEnum.TXF.getFplxDm().equals(iu.getFplxdm())) {
                invoiceType = FplxEnum.TXF.getFplxDm();
            }
        }
        String invoiceNo = pramsMap.get("invoiceNo");
        String invoiceDate = pramsMap.get("invoiceDate");
        String invoiceAmount = pramsMap.getOrDefault("invoiceAmount", "");
        String taxAmount = pramsMap.getOrDefault("taxAmount", "");
        String checkCode = pramsMap.getOrDefault("checkCode", "");
        String gfmc = pramsMap.getOrDefault("gfmc", "");
        String xfmc = pramsMap.getOrDefault("xfmc", "");
        String saveHistory = pramsMap.getOrDefault("saveHistory", "");
        String taxNo = pramsMap.getOrDefault("taxNo", "");
        String company = pramsMap.get("company");
        checkLog.setCheckUser(userId);
        if(FplxEnum.QDZZP.getFplxDm().equals(invoiceType) || FplxEnum.QDPP.getFplxDm().equals(invoiceType)){
            checkLog.setInvoiceType(pramsMap.get("invoiceType"));
            if (!StringHelper.isBlank(invoiceAmount)) {
                try {
                    checkLog.setTotalAmount(BigDecimal.valueOf(new DecimalFormat().parse(invoiceAmount).doubleValue()));
                    checkLog.setInvoiceAmount(null);
                } catch (Exception e) {
                    checkLog.setTotalAmount(new BigDecimal("0"));
                }
            }
        }else {
            if (!StringHelper.isBlank(invoiceAmount)) {
                try {
                    checkLog.setInvoiceAmount(BigDecimal.valueOf(new DecimalFormat().parse(invoiceAmount).doubleValue()));
                } catch (Exception e) {
                    checkLog.setInvoiceAmount(new BigDecimal("0"));
                }
            }
            checkLog.setInvoiceCode(invoiceCode);
            checkLog.setInvoiceType(invoiceType);
        }

        checkLog.setInvoiceNo(invoiceNo);

        if (!StringHelper.isBlank(invoiceDate)) {
            checkLog.setInvoiceDate(DateUtils.strToDate(invoiceDate));
        }
        checkLog.setHandleDate(DateUtils.getSqlDateLong());

        if (!StringHelper.isBlank(taxAmount)) {
            try {
                checkLog.setTaxAmount(BigDecimal.valueOf(new DecimalFormat().parse(taxAmount).doubleValue()));
            } catch (Exception e) {
                checkLog.setTaxAmount(new BigDecimal("0"));
            }
        }
        if (!StringHelper.isBlank(checkCode)) {
            checkLog.setCheckCode(checkCode);
        }
        checkLog.setBuyerName(gfmc);
        checkLog.setSalerName(xfmc);

        JSONObject queryInvoiceResult =
                invoiceQueryUtil.queryInvoice(invoiceCode, invoiceNo, invoiceDate, invoiceAmount, checkCode, taxNo,invoiceType);
        queryInvoiceResult.put("scanId", pramsMap.get("scanId"));
        queryInvoiceResult.put("company", pramsMap.get("company"));
        if (queryInvoiceResult.containsKey("returnCode")) {
            // 查验出错
            checkLog.setHandleCode(queryInvoiceResult.getString("returnCode"));
            checkLog.setCheckMassege(queryInvoiceResult.getString("returnMessage"));
            if ("Y".equals(saveHistory)) {
                // 保存查验主表
                TdxCheckRecordInvoice checkRecordInvoice = new TdxCheckRecordInvoice();
                checkRecordInvoice.setScanId(pramsMap.get("scanId"));
                checkRecordInvoice.setUuid((StringUtils.isBlank(invoiceCode)?"":invoiceCode) + invoiceNo);
                checkRecordInvoice.setCheckUser(userId);
                checkRecordInvoice.setFphm(invoiceNo);
                checkRecordInvoice.setFpzl(invoiceType);
                checkRecordInvoice.setCompany(pramsMap.get("company"));
                if (!StringHelper.isBlank(invoiceDate)) {
                    checkRecordInvoice.setKprq(DateUtils.strToStrDate2(invoiceDate));
                }
                if(FplxEnum.QDZZP.getFplxDm().equals(invoiceType) || FplxEnum.QDPP.getFplxDm().equals(invoiceType)){
                    if (!StringHelper.isBlank(invoiceAmount)) {
                        checkRecordInvoice.setJshj(invoiceAmount);
                    }
                }else {
                    checkRecordInvoice.setFpdm(invoiceCode);
                    if (!StringHelper.isBlank(invoiceAmount)) {
                        checkRecordInvoice.setJe(invoiceAmount);
                    }
                }

                if (!StringHelper.isBlank(taxAmount)) {
                    checkRecordInvoice.setSe(taxAmount);
                }
                if (!StringHelper.isBlank(checkCode)) {
                    checkRecordInvoice.setJym(checkCode);
                }
                checkRecordInvoice.setPdfMd5(Long.valueOf(scanIdUtils.createSerialNum()));
                checkRecordInvoice.setCreateDate(DateUtils.getSqlDateLong());
                checkRecordInvoice.setCyjgCode(queryInvoiceResult.getString("returnCode"));
                checkRecordInvoice.setCyjgTip(queryInvoiceResult.getString("returnMessage"));
                signCheckRecordService.saveCheckRecordInvoice(checkRecordInvoice, pramsMap.get("dbName"));
            }
        } else {
            // 查验成功
            if ("Y".equals(saveHistory)) {
                // 查验调用，保存查验记录
                signSaveCheckInfoService.saveCheckInfo(queryInvoiceResult, pramsMap.get("userid"), pramsMap.get("dbName"));
                if(StringUtils.isNotBlank(queryInvoiceResult.getString("invoiceType"))){
                    checkLog.setInvoiceType(queryInvoiceResult.getString("invoiceType"));
                }
            }
            checkLog.setHandleCode(queryInvoiceResult.getString("resultCode"));
            checkLog.setCheckMassege(queryInvoiceResult.getString("resultTip"));
            try {
                checkLog.setTaxAmount(queryInvoiceResult.getBigDecimal("taxAmount"));
            } catch (Exception e) {
                checkLog.setTaxAmount(new BigDecimal(0));
            }
            try {
                checkLog.setTotalAmount(queryInvoiceResult.getBigDecimal("totalAmount"));
            } catch (Exception e) {
                checkLog.setTotalAmount(new BigDecimal(0));
            }
            try {
                if (FplxEnum.ESC.getFplxDm().equals(invoiceType)) {
                    checkLog.setInvoiceAmount(queryInvoiceResult.getBigDecimal("carPrice"));
                } else {
                    checkLog.setInvoiceAmount(queryInvoiceResult.getBigDecimal("invoiceAmount"));
                }
            } catch (Exception e) {
                checkLog.setInvoiceAmount(new BigDecimal(0));
            }
            checkLog.setBuyerName(queryInvoiceResult.getString("buyerName"));
            checkLog.setSalerName(queryInvoiceResult.getString("salerName"));
            if(FplxEnum.ESC.getFplxDm().equals(invoiceType)){
                checkLog.setBuyerName(queryInvoiceResult.getString("buyerUnitOrIndividual"));
                checkLog.setSalerName(queryInvoiceResult.getString("sellerUnitOrIndividual"));
            }
        }
        // 查验调用，保存查验日志
        if ("Y".equals(saveHistory)) {
            DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_WRITE);
            super.save(checkLog);
        }

        return checkLog;
    }

    /**
     * 转换扫描查验显示对象
     *
     * @param checkLog
     *            扫描查验结果
     * @return 返回结果
     *
     */
    private ExtSmcyVO convertToSmcyView(TDxCheckLog checkLog) {
        ExtSmcyVO smcyVo = new ExtSmcyVO();
        String id = checkLog.getInvoiceCode() + "-" + checkLog.getInvoiceNo();
        smcyVo.setId(id);
        smcyVo.setCheckMassege(checkLog.getCheckMassege());
        smcyVo.setInvoiceCode(checkLog.getInvoiceCode());
        smcyVo.setInvoiceNo(checkLog.getInvoiceNo());
        if (checkLog.getInvoiceDate() != null) {
            smcyVo.setInvoiceDate(DateUtils.dateToStr(checkLog.getInvoiceDate()));
        }
        if (checkLog.getTotalAmount()!= null) {
            smcyVo.setTotalAmount(
                    AmountFormatUtil.fmtMicrometer(MathUtil.round(checkLog.getTotalAmount().toPlainString())));
        }else {
            smcyVo.setTotalAmount("");
        }
        if (checkLog.getInvoiceAmount() != null) {
            smcyVo.setInvoiceAmount(
                    AmountFormatUtil.fmtMicrometer(MathUtil.round(checkLog.getInvoiceAmount().toPlainString())));
        } else {
            smcyVo.setInvoiceAmount("");
        }

        if (checkLog.getCheckCode() != null) {
            smcyVo.setCheckCode(checkLog.getCheckCode());
        } else {
            smcyVo.setCheckCode("");
        }
        smcyVo.setInvoiceType(checkLog.getInvoiceType());
        smcyVo.setHandleCode(checkLog.getHandleCode());
        smcyVo.setGfmc(checkLog.getBuyerName());
        smcyVo.setXfmc(checkLog.getSalerName());
        if ("0001".equals(checkLog.getHandleCode())) {
            smcyVo.setDetailState(true);
            smcyVo.setDelState(false);
            smcyVo.setEditState(false);
        } else {
            smcyVo.setDelState(true);
            smcyVo.setEditState(true);
            smcyVo.setDetailState(false);
        }
        return smcyVo;
    }

}