package com.dxhy.erp.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.enums.FpqsjgEnum;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.erp.dao.InvoiceDetailDao;
import com.dxhy.erp.dao.InvoiceElectronDao;
import com.dxhy.erp.dao.RecordInvoiceDao;
import com.dxhy.erp.dao.SysDeptDao;
import com.dxhy.erp.entity.*;
import com.dxhy.erp.service.CheckService;
import com.dxhy.erp.service.QsCheckTaskService;
import com.dxhy.erp.utils.CheckUtil;
import com.dxhy.erp.utils.InvoiceQueryUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @author dxhy
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
@Service("qsCheckTaskService")
@Slf4j
public class QsCheckTaskServiceImpl extends MpBaseServiceImpl<InvoiceElectronDao, InvoiceElectron>
    implements QsCheckTaskService {
    private static final String[] FPDMLIST = {"144031539110", "131001570151", "133011501118", "111001571071"};
    @Resource
    private InvoiceElectronDao invoiceElectronDao;
    @Resource
    private CheckService checkSerivice;

    @Resource
    private SysDeptDao sysDeptDao;
    @Resource
    private InvoiceDetailDao invoiceDetailDao;
    @Resource
    private RecordInvoiceDao recordInvoiceDao;

    @Resource
    private InvoiceQueryUtil invoiceQueryUtil;

    @Override
    public List<InvoiceElectron> selectElectronToCheck() {
        return invoiceElectronDao.selectElectronToCheck();
    }

    public CheckInvoiceParam checkInvoiceParamBuild(InvoiceElectron invoiceElectron) {
        CheckInvoiceParam param = new CheckInvoiceParam();
        param.setInvoiceCode(invoiceElectron.getInvoiceCode());
        param.setInvoiceNo(invoiceElectron.getInvoiceNo());
        param.setCheckCode(invoiceElectron.getCheckCode());
        param.setInvoiceAmount(invoiceElectron.getInvoiceAmount().toPlainString());
        param.setInvoiceDate(new SimpleDateFormat("yyyyMMdd").format(invoiceElectron.getInvoiceDate()));
        param.setInvoiceType(invoiceElectron.getInvoiceType());
        return param;
    }

    public FP getCheck(CheckInvoiceParam param) throws Exception {
        log.info("查询信息为=====" + param);
        CheckInvoiceParam entity = new CheckInvoiceParam();
        entity.setInvoiceCode(param.getInvoiceCode());
        entity.setInvoiceNo(param.getInvoiceNo());
        String date = param.getInvoiceDate();
        entity.setInvoiceDate(date);
        entity.setInvoiceType(param.getInvoiceType());
        entity.setInvoiceAmount(param.getInvoiceAmount());
        entity.setCheckCode(param.getCheckCode());
        log.info("请求的数据为" + entity);
        FP check = CheckUtil.getCheck(entity);
        log.info("响应的数据为" + check);
        return check;
    }

    @Override
    public void checkOne(InvoiceElectron invoiceElectron, String db) throws Exception {
        String invoiceDate = new SimpleDateFormat("yyyy-MM-dd").format(invoiceElectron.getInvoiceDate());
        if (!"10".equals(getFplx(invoiceElectron.getInvoiceCode()))) {
            // 不查验，直接存库
            invoiceElectron.setCheckReturnCode("1022");
            invoiceElectron.setNotes("解析失败，请联系结算员处理，谢谢！");
            invoiceElectron.setQsStatus("0");
            updateByInvoice(invoiceElectron, db);
        } else {

            // 进行查验处理
            JSONObject checkResult = invoiceQueryUtil.queryInvoice(invoiceElectron.getInvoiceCode(),
                invoiceElectron.getInvoiceNo(), invoiceDate, "", invoiceElectron.getCheckCode(),null,null);
            log.info("查验返回结果：{}", checkResult);
            invoiceElectron.setCheckReturnCode(checkResult.getString("resultCode"));
            if ("0001".equals(checkResult.getString("resultCode"))) {

                checkResult.put("company", invoiceElectron.getCompany());
                checkResult.put("scanId", invoiceElectron.getScanId());
                RecordInvoice record = getRecordInvoice(checkResult, invoiceElectron.getUserName(), "5");
                List<RecordInvoiceDetail> detailList = getRecordInvoiceDetail(checkResult);
                record.setScanStatus("0");
                int insertRecordInvoice = 0;

                try {

                    DynamicContextHolder.push(DbConstant.BASICS_READ);
                    SysDeptEntity deptEntity = sysDeptDao.getOrg(record.getGfTaxNo());
                    if (deptEntity != null) {

                        if (!deptEntity.getTaxname().equals(record.getGfName())) {
                            invoiceElectron.setCheckReturnCode("1026");
                            invoiceElectron.setNotes("签收失败,购方名称错误");
                            invoiceElectron.setQsStatus("0");
                            updateByInvoice(invoiceElectron, db);
                            return;
                        }
                    } else {
                        invoiceElectron.setCheckReturnCode("1007");
                        invoiceElectron.setNotes("签收失败,购方税号不在配置名单内");
                        invoiceElectron.setQsStatus("0");
                        updateByInvoice(invoiceElectron, db);
                        return;
                    }
                    if (!"0".equals(record.getInvoiceStatus())) {
                        invoiceElectron.setCheckReturnCode("1025");
                        invoiceElectron.setNotes("签收失败,此发票状态异常,请核实是否已红冲或者作废");
                        invoiceElectron.setQsStatus("0");
                        updateByInvoice(invoiceElectron, db);
                        return;

                    } else {
                        invoiceElectron.setCheckReturnCode("0001");
                        invoiceElectron.setNotes("签收成功");
                        invoiceElectron.setQsStatus("1");
                        updateByInvoice(invoiceElectron, db);
                        updateByInfo(record.getGfTaxNo(), record.getXfTaxNo(), record.getTotalAmount(),
                            record.getTaxAmount(), record.getInvoiceAmount(), record.getInvoiceDate(),
                            record.getInvoiceCode(), record.getInvoiceNo(), record.getGfName(), record.getXfName(), db);
                    }

                    try {
                        record.setQsDate(DateUtils.getSqlDateLong());
                        record.setCreateDate(DateUtils.getSqlDateLong());
                        record.setQsName(invoiceElectron.getUserName());
                        record.setQsStatus("1");
                        record.setQsType("5");
                        record.setSourceSystem("1");
                        record.setRequestId(invoiceElectron.getRequestId());
                        record.setVendorId(invoiceElectron.getVendorId());
                        record.setCompany(invoiceElectron.getCompany());
                        insertRecordInvoice = insertRecordInvoice(record, db);
                        log.debug("+++++++++" + record + "--------------");
                        if (insertRecordInvoice == 1) {
                            insertInvoiceDetail(record.getInvoiceCode(), record.getInvoiceNo(), detailList, db);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("入库底账表失败" + e);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.debug("========================" + insertRecordInvoice);
                }
            } else {
                invoiceElectron.setCheckReturnCode(checkResult.getString("returnCode"));
                invoiceElectron.setNotes(checkResult.getString("returnMessage"));
                invoiceElectron.setQsStatus("0");
                updateByInvoice(invoiceElectron, db);
            }
        }
    }

    public void updateByInvoice(InvoiceElectron invoice, String dbName) {
        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
        invoiceElectronDao.updateByInvoice(invoice);
    }

    public void updateByInfo(String gfTaxNo, String xfTaxNo, BigDecimal totalAmount, BigDecimal taxAmount,
        BigDecimal invoiceAmount, Date invoiceDate, String invoiceCode, String invoiceNo, String gfName, String xfName,
        String dbName) {
        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
        invoiceElectronDao.updateByInfo(gfTaxNo, xfTaxNo, totalAmount, taxAmount, invoiceAmount, invoiceDate,
            invoiceCode, invoiceNo, gfName, xfName);
    }

    public int insertRecordInvoice(RecordInvoice recordInvoice, String dbName) {
        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
        RecordInvoice uuid =
            recordInvoiceDao.selectOne(new QueryWrapper<RecordInvoice>().eq("uuid", recordInvoice.getUuid()));
        if (uuid != null) {
            return recordInvoiceDao.update(recordInvoice,
                new QueryWrapper<RecordInvoice>().eq("uuid", recordInvoice.getUuid()));
        } else {

            return recordInvoiceDao.insert(recordInvoice);
        }
    }

    public void insertInvoiceDetail(String invoiceCode, String invoiceNo, List<RecordInvoiceDetail> detailList,
        String dbName) throws Exception {
        DynamicContextHolder.push(dbName + DbConstant.DETAIL_WRITE);

        for (RecordInvoiceDetail recordInvoiceDetail : detailList) {
            recordInvoiceDetail.setUuid(invoiceCode + invoiceNo);
            recordInvoiceDetail.setInvoiceCode(invoiceCode);
            recordInvoiceDetail.setInvoiceNo(invoiceNo);
            invoiceDetailDao.insert(recordInvoiceDetail);
        }

    }

    private String getFplx(String fpdm) {
        log.info("从发票代码中获取发票类型,参数为：{}", fpdm);

        String fplx = "";
        if (fpdm.trim().length() == 12) {
            String fplxflag = fpdm.substring(7, 8);
            for (String s : FPDMLIST) {
                if (fpdm.equals(s)) {
                    fplx = "10";
                    break;
                }
            }
            if ("0".equals(fpdm.substring(0, 1)) && "11".equals(fpdm.substring(10, 12))) {
                fplx = "10";
            }
            if ("0".equals(fpdm.substring(0, 1)) && "12".equals(fpdm.substring(10, 12))) {
                fplx = "14";
            }
            boolean r = "06".equals(fpdm.substring(10, 12)) || "07".equals(fpdm.substring(10, 12));
            if ("0".equals(fpdm.substring(0, 1)) && r) {
                // 判断是否为卷式发票 第1位为0且第11-12位为06或07
                fplx = "11";
            }
            if ("2".equals(fplxflag) && !"0".equals(fpdm.substring(0, 1))) {
                fplx = "03";
            }
            boolean r1 = "04".equals(fpdm.substring(10, 12)) || "05".equals(fpdm.substring(10, 12));
            if ("0".equals(fpdm.substring(0, 1)) && r1) {
                fplx = "04";
            }
        } else if (fpdm.trim().length() == 10) {
            String fplxflag = fpdm.substring(7, 8);
            switch (fplxflag) {
                case "1":
                case "5":
                    fplx = "01";
                    break;
                case "6":
                case "3":
                    fplx = "04";
                    break;
                case "7":
                case "2":
                    fplx = "02";
                    break;
                default:
                    break;
            }
        }
        log.info("发票类型为：{}", fplx);
        return fplx;
    }

    public RecordInvoice getRecordInvoice(JSONObject queryInvoiceResult, String userName, String qsType) {
        RecordInvoice invoice = new RecordInvoice();

        String invoiceType = queryInvoiceResult.getString("invoiceType");
        String invoiceCode = queryInvoiceResult.getString("invoiceCode");
        String invoiceNo = queryInvoiceResult.getString("invoiceNo");
        String uuid = invoiceCode + invoiceNo;

        invoice.setInvoiceType(invoiceType);
        invoice.setInvoiceCode(invoiceCode);
        invoice.setInvoiceNo(invoiceNo);
        invoice.setUuid(uuid);
        if ("Y".equals(queryInvoiceResult.getString("isCancelled"))) {
            invoice.setInvoiceStatus(FpztEnum.ZF.getFpztDm(FpztEnum.ZF.getIndex()));
        } else if ("N".equals(queryInvoiceResult.getString("isCancelled"))) {
            invoice.setInvoiceStatus(FpztEnum.ZC.getFpztDm(FpztEnum.ZC.getIndex()));
        } else {
            invoice.setInvoiceStatus(queryInvoiceResult.getString("isCancelled"));
        }
        invoice.setInvoiceAmount(queryInvoiceResult.getBigDecimal("invoiceAmount"));
        invoice.setTaxAmount(queryInvoiceResult.getBigDecimal("taxAmount"));
        invoice.setTotalAmount(queryInvoiceResult.getBigDecimal("totalAmount"));
        invoice.setInvoiceDate(queryInvoiceResult.getDate("invoiceDate"));
        invoice.setGfAddressAndPhone(queryInvoiceResult.getString("buyerAddressPhone"));
        invoice.setGfBankAndNo(queryInvoiceResult.getString("buyerAccount"));
        invoice.setGfName(queryInvoiceResult.getString("buyerName"));
        invoice.setGfTaxNo(queryInvoiceResult.getString("buyerTaxNo"));
        invoice.setXfAddressAndPhone(queryInvoiceResult.getString("salerAddressPhone"));
        invoice.setXfBankAndNo(queryInvoiceResult.getString("buyerAccount"));
        invoice.setXfName(queryInvoiceResult.getString("salerName"));
        invoice.setXfTaxNo(queryInvoiceResult.getString("salerTaxNo"));
        invoice.setMachinecode(queryInvoiceResult.getString("machineNo"));
        invoice.setRemark(queryInvoiceResult.getString("remark"));
        invoice.setCheckCode(queryInvoiceResult.getString("checkCode"));
        invoice.setTxfbz(queryInvoiceResult.getString("txfbz"));
        invoice.setSourceSystem("1");
        invoice.setCompany(queryInvoiceResult.getString("company"));
        if (FplxEnum.JDC.getFplxDm().equals(invoiceType)) {
            invoice.setDetailYesorno(0);
        } else {
            if (queryInvoiceResult.containsKey("detailList")) {
                JSONArray dataArray = queryInvoiceResult.getJSONArray("detailList");
                if (dataArray != null && dataArray.size() > 0) {
                    invoice.setDetailYesorno(1);
                } else {
                    invoice.setDetailYesorno(0);
                }
            } else {
                invoice.setDetailYesorno(0);
            }
        }
        invoice.setCreateDate(new Date());
        invoice.setLastUpdateDate(new Date());
        invoice.setQsDate(DateUtils.getSqlDateLong());
        invoice.setQsStatus(FpqsjgEnum.YQS.getQsjgDm());
        invoice.setQsType(qsType);
        invoice.setValid("1");
        invoice.setQsName(userName);
        invoice.setRzhYesorno("0");
        invoice.setAuthStatus("0");
        invoice.setScanId(queryInvoiceResult.getString("scanId"));
        return invoice;
    }

    public List<RecordInvoiceDetail> getRecordInvoiceDetail(JSONObject queryInvoiceResult) {
        if (queryInvoiceResult.containsKey("detailList")) {
            JSONArray dataArray = queryInvoiceResult.getJSONArray("detailList");
            if (dataArray != null && dataArray.size() > 0) {
                String invoiceType = queryInvoiceResult.getString("invoiceType");
                String invoiceCode = queryInvoiceResult.getString("invoiceCode");
                String invoiceNo = queryInvoiceResult.getString("invoiceNo");
                String uuid = invoiceCode + invoiceNo;
                List<RecordInvoiceDetail> invoiceDetailList = new ArrayList<>(dataArray.size());
                for (int i = 0; i < dataArray.size(); i++) {
                    JSONObject invoiceDetailQuery = dataArray.getJSONObject(i);
                    RecordInvoiceDetail invoiceDetail = new RecordInvoiceDetail();
                    invoiceDetail.setUuid(uuid);
                    invoiceDetail.setInvoiceCode(invoiceCode);
                    invoiceDetail.setInvoiceNo(invoiceNo);
                    invoiceDetail.setDetailNo(invoiceDetailQuery.getInteger("detailNo"));
                    invoiceDetail.setGoodsName(invoiceDetailQuery.getString("goodsName"));
                    invoiceDetail.setModel(invoiceDetailQuery.getString("specificationModel"));
                    invoiceDetail.setUnit(invoiceDetailQuery.getString("unit"));
                    invoiceDetail.setNum(invoiceDetailQuery.getString("num"));
                    invoiceDetail.setUnitPrice(invoiceDetailQuery.getString("unitPrice"));
                    invoiceDetail.setDetailAmount(invoiceDetailQuery.getString("detailAmount"));
                    invoiceDetail.setTaxRate(invoiceDetailQuery.getString("taxRate"));
                    invoiceDetail.setTaxAmount(invoiceDetailQuery.getString("taxAmount"));
                    if (FplxEnum.TXF.getFplxDm().equals(invoiceType)) {
                        // 通行费发票
                        invoiceDetail.setCph(invoiceDetailQuery.getString("cph"));
                        invoiceDetail.setLx(invoiceDetailQuery.getString("lx"));
                        invoiceDetail.setTxrqq(invoiceDetailQuery.getString("txrqq"));
                        invoiceDetail.setTxrqz(invoiceDetailQuery.getString("txrqz"));
                    }
                    invoiceDetailList.add(invoiceDetail);
                }
                return invoiceDetailList;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }
}
