package com.dxhy.core.service.singletable.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.api.model.invoice.TDxRecordInvoice;
import com.dxhy.api.model.invoice.invoiceCheck.TDxCheckLog;
import com.dxhy.common.constant.ConfigureConstant;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.InvoiceUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.util.StringHelper;
import com.dxhy.common.utils.CommonUtil;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.core.dao.CoreTDxCheckLogDao;
import com.dxhy.core.dao.CoreTDxRecordInvoiceDao;
import com.dxhy.core.model.CoreSmcyVO;
import com.dxhy.core.service.singletable.CoreInvoiceQueryService;
import com.dxhy.core.service.singletable.CoreSaveInvoiceInfoService;
import com.dxhy.core.util.InvoiceQueryUtil;
import com.dxhy.jxpt.baseService.poolPush.PoolLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 查验业务处理接口实现类
 *
 * @author 陈刚扬
 * @date 2020/10/28
 * @return
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
@Service("coreInvoiceQueryService")
@Slf4j

public class CoreInvoiceQueryServiceImpl extends MpBaseServiceImpl<CoreTDxCheckLogDao, TDxCheckLog>
    implements CoreInvoiceQueryService {

    @Resource
    private CoreSaveInvoiceInfoService coreSaveInvoiceInfoService;
    @Resource
    private PoolLogService poolLogService;
    @Resource
    private CoreTDxRecordInvoiceDao coreTDxRecordInvoiceDao;

    @Resource
    private InvoiceQueryUtil invoiceQueryUtil;

    @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<CoreSmcyVO> returnList = new ArrayList<>();
        CoreSmcyVO smcyVo = this.convertToSmcyView(checkLog);
        returnList.add(smcyVo);

        json.put("datalist", returnList);

        return super.responseResult(json);
    }

    /**
     * 查验一张发票信息，此方法为公共方法，多种查验方式公用
     *
     * @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)) {
//            InvoiceUtil iu = new InvoiceUtil(invoiceCode);
//            invoiceType = iu.getFplxdm();
//        }
        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 taxNo = pramsMap.getOrDefault("taxNo", "");

        DynamicContextHolder.push("business" + DbConstant.BUSINESS_READ);
        TDxRecordInvoice tri = coreTDxRecordInvoiceDao.selectOne(new QueryWrapper<TDxRecordInvoice>().eq("invoice_code", invoiceCode).eq("invoice_no", invoiceNo));
        if (tri!=null) {
            taxNo = tri.getGfTaxNo();
        }
        DynamicContextHolder.push( DbConstant.BASICS_READ);

        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", "");


        checkLog.setCheckUser(userId);
        checkLog.setInvoiceType(invoiceType);
        checkLog.setInvoiceCode(invoiceCode);
        checkLog.setInvoiceNo(invoiceNo);

        if (!StringHelper.isBlank(invoiceDate)) {
            checkLog.setInvoiceDate(DateUtils.strToDate(invoiceDate));
        }
        checkLog.setHandleDate(DateUtils.getSqlDateLong());
        if (!StringHelper.isBlank(invoiceAmount)) {
            try {
                checkLog.setInvoiceAmount(BigDecimal.valueOf(new DecimalFormat().parse(invoiceAmount).doubleValue()));
            } catch (Exception e) {
                checkLog.setInvoiceAmount(new BigDecimal("0"));
            }
        }
        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);

        if (FplxEnum.QDZZP.getFplxDm().equals(invoiceType) ||
                FplxEnum.QDPP.getFplxDm().equals(invoiceType) ||
                FplxEnum.TLKP.getFplxDm().equals(invoiceType) ||
                FplxEnum.HKDZFP.getFplxDm().equals(invoiceType)) {
            invoiceNo = invoiceCode + invoiceNo;
            invoiceCode = "";
        }

        JSONObject queryInvoiceResult =
            invoiceQueryUtil.queryInvoice(invoiceCode, invoiceNo, invoiceDate, invoiceAmount, checkCode, taxNo,invoiceType );
        queryInvoiceResult.put("scanId", pramsMap.get("scanId"));
        queryInvoiceResult.put("company", pramsMap.get("company"));
        checkLog.setHandleCode(queryInvoiceResult.getString("returnCode"));
        checkLog.setCheckMassege(queryInvoiceResult.getString("returnMessage"));
        if (!queryInvoiceResult.containsKey("returnCode")) {

            // 查验成功

            // 未补发票明细调用，保存底账信息
            coreSaveInvoiceInfoService.saveQueryInvoiceResult(queryInvoiceResult, pramsMap.get("dbName"));
            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 {
                checkLog.setInvoiceAmount(queryInvoiceResult.getBigDecimal("invoiceAmount"));
            } catch (Exception e) {
                checkLog.setInvoiceAmount(new BigDecimal(0));
            }
            checkLog.setBuyerName(queryInvoiceResult.getString("buyerName"));
            checkLog.setSalerName(queryInvoiceResult.getString("salerName"));
            checkLog.setInvoiceType(queryInvoiceResult.getString("invoiceType"));

            //推送新票池记录表
            poolLogService.pushChangeToPool(ConfigureConstant.POOL_SJLX_JXFP_1, CommonUtil.getUuid(queryInvoiceResult.getString("invoiceCode"),queryInvoiceResult.getString("invoiceNo")), ConfigureConstant.POOL_BGLX_SJBG_1);
        }
        return checkLog;
    }

    /**
     * 判断日期是否合法
     *
     * @param date
     *            日期
     * @return 返回
     */
    public static boolean checkValiDate(String date) {
        try {
            int year = Integer.parseInt(date.substring(0, 4));
            if (year < 1901) {
                return false;
            }
            int month = Integer.parseInt(date.substring(5, 7));
            if (month > 12) {
                return false;
            }
            int day = Integer.parseInt(date.substring(8, 10));
            if (day > 31) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    private CoreSmcyVO convertToSmcyView(TDxCheckLog checkLog) {
        CoreSmcyVO smcyVo = new CoreSmcyVO();
        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.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());
        return smcyVo;
    }

}
