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

import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.api.model.invoice.TDxRecordEntity;
import com.dxhy.api.model.invoice.TDxRecordInvoice;
import com.dxhy.common.constant.CoreConstants;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.core.dao.CoreInvoiceDownDao;
import com.dxhy.core.job.dao.*;
import com.dxhy.core.job.entity.*;
import com.dxhy.core.job.pojo.Authorize;
import com.dxhy.core.job.pojo.BaseQueJson;
import com.dxhy.core.job.pojo.BaseResJson;
import com.dxhy.core.job.pojo.GlobalInfo;
import com.dxhy.core.job.pojo.down.*;
import com.dxhy.core.job.service.InvoiceDownService;
import com.dxhy.core.job.service.InvoiceInterfaceService;
import com.dxhy.core.job.utils.TransitionUtils;
import com.dxhy.core.util.GzipStringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 功能描述
 *
 * @author 陈刚扬
 * @date 2020/10/28
 * @return
 */

@Service("InvoiceDownService")
@Slf4j
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
public class InvoiceDownServiceImpl implements InvoiceDownService {

    @Resource
    private CoreInvoiceDownDao coreInvoiceDownDao;

    @Resource
    private TDxRecordInvoiceJobDao tDxRecordInvoiceJobDao;
    @Resource
    private DataPlatformFailRecordDao dataPlatformFailRecordDao;
    @Resource
    private DataPlatformRecordDao dataPlatformRecordDao;
    @Resource
    private DataPlatformSaleRecordDao dataPlatformSaleRecordDao;
    @Resource
    private InvoiceInterfaceService invoiceInterfaceService;

    @Resource
    private TDxSaleRecordInvoiceJobDao tDxSaleRecordInvoiceJobDao;
    @Resource
    private TDxVehicleSaleInvoiceDao tDxVehicleSaleInvoiceDao;
    @Resource
    private TDxVehicleSaleInvoiceSalesDao tDxVehicleSaleInvoiceSalesDao;

    @Resource
    private TDxRecordInvoiceDetailJobDao tDxRecordInvoiceDetailDao;
    @Resource
    private InvoiceDownDetaiInsertDao invoiceDownDetaiInsertDao;
    @Resource
    private InvoiceDownDetaiSaleInsertDao invoiceDownDetaiSaleInsertDao;

    @Override
    public void sendRequest(String taxno, String dbName, String aceId, String aceKey, String invoiceTypes,
        String company, String dataType) {

        // 请求通用头
        GlobalInfo globalInfo = new GlobalInfo();
        // 请求通用
        Authorize authorize = new Authorize();
        // 具体参数
        InvoiceDownData collectData = new InvoiceDownData();
        BaseQueJson bqj = new BaseQueJson();
        String[] invoiceType = invoiceTypes.split(",");
        for (int i = 0; i < invoiceType.length; i++) {
            try {
                // 封装参数
                globalInfo.setAppId("JXFP");
                globalInfo.setVersion(CoreConstants.version);
                String exchangeId = getDataExchangeId();
                globalInfo.setDataExchangeId(exchangeId);
                globalInfo.setInterfaceCode(CoreConstants.invoiceDown);
                globalInfo.setEnterpriseCode(CoreConstants.enterpriseCode);
                authorize.setAppSecId(aceId);
                collectData.setTaxno(taxno);
                collectData.setDataType(dataType);
                collectData.setInvoiceType(invoiceType[i]);
                DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
                String dataStr = JSONObject.toJSONString(collectData);
                log.info("data：" + dataStr);
                String base64Data = Base64.encode(dataStr);
                String appSec = makeAppSec(base64Data, exchangeId, CoreConstants.invoiceDown, aceId, aceKey);
                authorize.setAppSec(appSec);
                bqj.setData(base64Data);
                bqj.setAuthorize(authorize);
                bqj.setGlobalInfo(globalInfo);
                String collectDataStr = JSONObject.toJSONString(bqj);
                log.info("url:" + CoreConstants.invoiceDown);
                log.info("发票下载销项数据请求参数：" + collectDataStr);
                // 保存请求记录
                TDxHttpLogInvoiceDown httpLog = new TDxHttpLogInvoiceDown();
                httpLog.setTaxno(taxno);
                httpLog.setDataType(dataType);
                httpLog.setType("0");
                httpLog.setReqText(collectDataStr);
                // 得到返回报文，解析拿出返回的数量，累加用于判断数量
                httpLog.setReqDate(new Date());
                String responseJson = HttpUtil.post(CoreConstants.invoiceDownUrl, collectDataStr, 240000);
                httpLog.setResDate(new Date());
                log.info(responseJson);
                // 根据发票类型保存不同实体
                BaseResJson gatherData = JSONObject.parseObject(responseJson, BaseResJson.class);
                log.info("返回报文：" + responseJson);
                if (gatherData != null) {
                    log.info(gatherData.toString());
                    String base64data = gatherData.getData();
                    String dataJson = "{}";
                    if (base64data != null) {
                        dataJson = Base64.decodeStr(base64data);
                    }
                    log.info("data体：" + dataJson);
                    httpLog.setResText(responseJson);
                    httpLog.setStatus("0");
                    httpLog.setCompany(company);
                    httpLog.setInvoiceType(invoiceType[i]);
                    DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);

                    // 根据data里判断是否需要继续请求
                    JSONArray array = JSONArray.parseArray(dataJson);
                    if (array.size() > 0) {
                        for (int j = 0; j < array.size(); j++) {
                            requestInvoice(taxno, dbName, aceId, aceKey, company, globalInfo, authorize, bqj,
                                invoiceType, i, exchangeId, array, j, dataType);
                        }
                        httpLog.setStatus("1");
                    } else {
                        httpLog.setStatus("1");
                    }
                    coreInvoiceDownDao.insert(httpLog);
                }
            } catch (Exception e) {
               log.info("业务处理异常：{}", e);

            }
        }

    }

    private void requestInvoice(String taxno, String dbName, String aceId, String aceKey, String company,
        GlobalInfo globalInfo, Authorize authorize, BaseQueJson bqj, String[] invoiceType, int i, String exchangeId,
        JSONArray array, int j, String dataType) {
        String id = array.getJSONObject(j).getString("id");
        JSONObject requestJson = new JSONObject();
        requestJson.put("id", Long.valueOf(id));
        requestJson.put("taxno", taxno);
        String base64Data = Base64.encode(requestJson.toJSONString());
        String appSec = makeAppSec(base64Data, exchangeId, CoreConstants.invoiceDownResult, aceId, aceKey);
        authorize.setAppSec(appSec);
        bqj.setData(base64Data);
        bqj.setAuthorize(authorize);
        globalInfo.setInterfaceCode(CoreConstants.invoiceDownResult);
        bqj.setGlobalInfo(globalInfo);
        String collectDataStr = JSONObject.toJSONString(bqj);
        log.info("url:" + CoreConstants.invoiceDownUrl);
        log.info("发票下载销项具体发票数据请求参数：" + collectDataStr);
        // 保存请求记录
        TDxHttpLogInvoiceDown httpLog = new TDxHttpLogInvoiceDown();
        httpLog.setTaxno(taxno);
        httpLog.setDataType(dataType);
        httpLog.setType("1");
        httpLog.setReqText(collectDataStr);
        // 得到返回报文，解析拿出返回的数量，累加用于判断数量
        httpLog.setReqDate(new Date());
        String responseJson = HttpUtil.post(CoreConstants.invoiceDownUrl, collectDataStr, 240000);
        httpLog.setResDate(new Date());
        log.info(responseJson);
        // 根据发票类型保存不同实体
        BaseResJson gatherData = JSONObject.parseObject(responseJson, BaseResJson.class);
        log.info("返回报文：" + responseJson);
        if (gatherData != null) {
            log.info(gatherData.toString());
            httpLog.setResText(responseJson);
            httpLog.setStatus("0");
            httpLog.setCompany(company);
            httpLog.setInvoiceType(invoiceType[i]);
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
            coreInvoiceDownDao.insert(httpLog);
        }
    }

    /**
     * 获取时间戳
     *
     * @return String
     */
    public String getDataExchangeId() {
        // enterpriseCode+8 位日期
        // (YYYYMMDD)+9 位序列号
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        for (int i = 0; i < 9; i++) {
            sb.append(rand.nextInt(10));
        }
        String data = sb.toString();
        return CoreConstants.enterpriseCode + simpleDateFormat.format(new Date()) + data;
    }

    /**
     * 加密方法
     */
    public String makeAppSec(String data, String dataExchangeId, String interfaceCode, String aceId, String aceKey) {
        String srcStr =
            "POST/down/invoice/dii?authorize={\"appSecId\":\"" + aceId + "\"}&globalInfo={\"appId\":\"" + CoreConstants.appId
                + "\",\"version\":\"" + CoreConstants.version + "\",\"interfaceCode\":\"" + interfaceCode + "\",\"enterpriseCode\":\""
                + CoreConstants.enterpriseCode + "\",\"dataExchangeId\":\"" + dataExchangeId + "\"}&" + "data=" + data + "";
        log.info("待加密的请求：" + srcStr);
        SecretKeySpec keySpec = null;
        keySpec = new SecretKeySpec(aceKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA1");
        } catch (NoSuchAlgorithmException e) {
           log.info("业务处理异常：{}", e);
        }
        try {
            mac.init(keySpec);
        } catch (InvalidKeyException e) {
           log.info("业务处理异常：{}", e);
        }
        byte[] singBytes = new byte[0];
        singBytes = mac.doFinal(srcStr.getBytes(StandardCharsets.UTF_8));
        String appSec = Base64.encode(singBytes);
        log.info("interfaceCode接口生成的加密串=appSec--");
        return appSec;
    }

    /**
     * 获取批次号
     */
    public String getBatchNo() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String date = simpleDateFormat.format(new Date());
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        for (int i = 0; i < 24; i++) {
            sb.append(rand.nextInt(10));
        }
        String data = sb.toString();
        return date + data;
    }

    @Override
    public List<String> getNoParse() {
        return coreInvoiceDownDao.getNoParse();
    }

    @Override
    public void parse(String taxno, String db) throws IOException {
        DynamicContextHolder.push(db + DbConstant.BUSINESS_READ);
        List<TDxHttpLogInvoiceDown> logs = getNotParseHttpLogs(taxno);
        if (logs != null && logs.size() > 0) {
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            this.updateNotParseHttpLogsStatus(logs);
            for (TDxHttpLogInvoiceDown tDxHttpLog : logs) {
                String responseJson = tDxHttpLog.getResText();
                Long logid = tDxHttpLog.getLogId();
                log.info("开始解析报文id:" + logid + "  报文内容：" + responseJson);
                // 根据发票类型保存不同实体
                BaseResJson gatherData = JSONObject.parseObject(responseJson, BaseResJson.class);
                log.info("返回报文：" + responseJson);
                log.info(gatherData.toString());
                String base64data = gatherData.getData();
                if (base64data != null) {
                    String dataStr = GzipStringUtil.uncompress(base64data);
                    // String dataJson = Base64.decodeStr(dataStr);
                    log.info("data体：" + dataStr);
                    GatherInvoiceDownData gather = JSONObject.parseObject(dataStr, GatherInvoiceDownData.class);
                    if ("0".equals(gather.getInvoiceNum())) {
                        tDxHttpLog.setStatus("1");
                        tDxHttpLog.setTotal("0");
                        DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
                        coreInvoiceDownDao.updateHttoLogById(tDxHttpLog);
                        continue;
                    }
                    String type = tDxHttpLog.getInvoiceType();
                    if ("01".equals(type) || "08".equals(type) || "14".equals(type) || "11".equals(type)
                        || "04".equals(type) || "10".equals(type)) {
                        parseInvoice(logid, tDxHttpLog, dataStr, db);
                    } else if ("03".equals(type)) {
                        parseVehicleInvoice(tDxHttpLog, dataStr, db);
                    } else if ("15".equals(type)) {
                        parseEsc(tDxHttpLog, dataStr, db);
                    }
                } else {
                    tDxHttpLog.setStatus("1");
                    tDxHttpLog.setTotal("0");
                    DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
                    coreInvoiceDownDao.updateHttoLogById(tDxHttpLog);
                }
            }
        }
    }

    private void parseVehicleInvoice(TDxHttpLogInvoiceDown tDxHttpLog, String dataJson, String db) {
        JSONObject json = JSONObject.parseObject(dataJson);
        JSONArray records = json.getJSONArray("invoices");
        List<VehicleInvoiceModel> invoicesList = records.toJavaList(VehicleInvoiceModel.class);
        String total = invoicesList.size() + "";
        boolean flg = false;
        for (VehicleInvoiceModel dataPlatformInvoiceInfo : invoicesList) {
            // 解析处理
            flg = updateVehicleSaleInvoiceAndDetail(dataPlatformInvoiceInfo, db, tDxHttpLog.getCompany(), tDxHttpLog);

        }
        if (flg) {
            tDxHttpLog.setStatus("2");
            tDxHttpLog.setTotal(total);
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            coreInvoiceDownDao.updateHttpLogById(tDxHttpLog);
        } else {
            tDxHttpLog.setStatus("1");
            tDxHttpLog.setTotal(total);
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            coreInvoiceDownDao.updateHttpLogById(tDxHttpLog);
        }
    }

    private void parseEsc(TDxHttpLogInvoiceDown tDxHttpLog, String dataJson, String db) {
        JSONObject json = JSONObject.parseObject(dataJson);
        JSONArray records = json.getJSONArray("invoices");
        List<UsedcarInvoiceModel> invoicesList = records.toJavaList(UsedcarInvoiceModel.class);
        String total = invoicesList.size() + "";
        boolean flg = false;
        for (UsedcarInvoiceModel dataPlatformInvoiceInfo : invoicesList) {
            // 解析处理
            flg = updateVehicleSaleInvoiceAndDetail(dataPlatformInvoiceInfo, db, tDxHttpLog.getCompany(), tDxHttpLog);

        }
        if (flg) {
            tDxHttpLog.setStatus("2");
            tDxHttpLog.setTotal(total);
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            coreInvoiceDownDao.updateHttpLogById(tDxHttpLog);
        } else {
            tDxHttpLog.setStatus("1");
            tDxHttpLog.setTotal(total);
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            coreInvoiceDownDao.updateHttpLogById(tDxHttpLog);
        }
    }

    /**
     * 机动车发票更新
     *
     * @param dataPlatformInvoiceInfo
     *            发票信息
     * @param db
     * @param tDxHttpLog
     */
    private boolean updateVehicleSaleInvoiceAndDetail(Object dataPlatformInvoiceInfo, String db, String company,
        TDxHttpLogInvoiceDown tDxHttpLog) {
        boolean flg;
        Map<String, Object> map = null;
        try {
            if ("03".equals(tDxHttpLog.getInvoiceType())) {
                map = getVehicleInfo((VehicleInvoiceModel)dataPlatformInvoiceInfo, tDxHttpLog);
            }
            if ("15".equals(tDxHttpLog.getInvoiceType())) {
                map = getEscInfo((UsedcarInvoiceModel)dataPlatformInvoiceInfo, tDxHttpLog);
            }

            TDxVehicleSaleInvoice tDxVehicleSaleInvoice = (TDxVehicleSaleInvoice)map.get("vehicleSaleInvoice");
            TDxRecordEntity invoice = null;
            invoice = (TDxRecordEntity)map.get("veinfo");
            String code = invoice.getInvoiceCode();
            String no = invoice.getInvoiceNo();
            invoice.setUuid(code + no);
            invoice.setCompany(company);
            DynamicContextHolder.push(db + DbConstant.BUSINESS_READ);
            // 判断是否有数据
            TDxRecordInvoice record = null;
            if ("1".equals(tDxHttpLog.getDataType())) {
                record = tDxRecordInvoiceJobDao.findInvoiceByCodeAndNo(code, no);
            }
            if ("2".equals(tDxHttpLog.getDataType())) {
                record = tDxRecordInvoiceJobDao.findSaleInvoiceByCodeAndNo(code, no);
            }
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            if (record != null) {
                if ("0".equals(record.getSourceSystem()) || "1".equals(record.getSourceSystem())
                    || !record.getInvoiceStatus().equals(invoice.getInvoiceStatus())) {
                    if ("1".equals(tDxHttpLog.getDataType())) {
                        TDxRecordInvoice tri = new TDxRecordInvoice();
                        BeanUtils.copyProperties(invoice,tri);
                        invoiceInterfaceService.isExistInvoice(tri, db, "2");
                    }
                    if ("2".equals(tDxHttpLog.getDataType())) {
                        TDxSaleRecordInvoiceJobEntity tsri = new TDxSaleRecordInvoiceJobEntity();
                        BeanUtils.copyProperties(invoice,tsri);
                        invoiceInterfaceService.isExistSaleInvoice(tsri, db, "2");
                    }
                } else {
                    RecordInvoiceDownModel data = new RecordInvoiceDownModel();
                    data.setInvoiceCode(code);
                    data.setInvoiceNo(no);
                    // 不做更新，记录日志表
                    insertDataPlatformLog(data, db);
                }
            } else {
                if (!"0".equals(invoice.getInvoiceStatus())) {
                    invoice.setStatusUpdateDate(new Date());
                }
                // 第一次插入添加票池采集字段
                invoice.setCollectStatus("1");
                invoice.setCollectFrom("1");
                invoice.setCollectDate(new Date());
                invoice.setPoolStatus("0");
                //记录通道来源
                invoice.setTdly("1");
                if ("1".equals(tDxHttpLog.getDataType())) {
                    TDxRecordInvoice tri = new TDxRecordInvoice();
                    BeanUtils.copyProperties(invoice,tri);
                    tDxRecordInvoiceJobDao.insert(tri);
                }
                if ("2".equals(tDxHttpLog.getDataType())) {
                    TDxSaleRecordInvoiceJobEntity tsri = new TDxSaleRecordInvoiceJobEntity();
                    BeanUtils.copyProperties(invoice,tsri);
                    tDxSaleRecordInvoiceJobDao.insert(tsri);
                }
            }

            String invoiceCode = invoice.getInvoiceCode();
            String invoiceNo = invoice.getInvoiceNo();
            invoice.setUuid(invoiceCode + invoiceNo);
            tDxVehicleSaleInvoice.setUuid(invoiceCode + invoiceNo);
            log.info("机动车发票购方税号：" + invoice.getGfTaxNo());
            log.info("机动车发票uuid:" + invoiceCode + invoiceNo);

            int countDetail = 0;
            if ("1".equals(tDxHttpLog.getDataType())) {
                // 保存发票明细
                tDxRecordInvoiceDetailDao.delDetailJd(code + no);
                InvoiceCheckVehicleDetailModel invoiceCheckVehicleDetailModel =
                    TransitionUtils.getVehicleDetaiModel(tDxVehicleSaleInvoice);
                // 由于暂时不用发票获取接口， 解放时参考查验定时任务转换实体再做插入
                tDxVehicleSaleInvoiceDao.insert(invoiceCheckVehicleDetailModel);
                countDetail = tDxRecordInvoiceDetailDao.getDetailJd(code + no);
            }
            if ("2".equals(tDxHttpLog.getDataType())) {
                // 保存发票明细
                tDxRecordInvoiceDetailDao.delDetailJdSales(code + no);
                InvoiceCheckVehicleDetailSalesModel invoiceCheckVehicleDetailSalesModel =
                    TransitionUtils.getVehicleDetaiSalesModel(tDxVehicleSaleInvoice);
                tDxVehicleSaleInvoiceSalesDao.insert(invoiceCheckVehicleDetailSalesModel);
                countDetail = tDxRecordInvoiceDetailDao.getDetailJdSales(code + no);
            }

            if (countDetail > 0) {
                invoice.setDetailYesorno("1");
            } else {
                invoice.setDetailYesorno("0");
            }
            if ("1".equals(tDxHttpLog.getDataType())) {
                TDxRecordInvoice tri = new TDxRecordInvoice();
                BeanUtils.copyProperties(invoice,tri);
                tDxRecordInvoiceDetailDao.updateDetailYesorno(tri);
            }
            if ("2".equals(tDxHttpLog.getDataType())) {
                TDxSaleRecordInvoiceJobEntity tsri = new TDxSaleRecordInvoiceJobEntity();
                BeanUtils.copyProperties(invoice,tsri);
                // 销项数据更新
                tDxRecordInvoiceDetailDao.updateSaleDetailYesorno(tsri);
            }
        } catch (ParseException e) {
           log.info("业务处理异常：{}", e);
            return true;
        }
        return false;

    }

    private Map<String, Object> getEscInfo(UsedcarInvoiceModel info, TDxHttpLogInvoiceDown tDxHttpLog)
        throws ParseException {
        TDxVehicleSaleInvoice vehicleSaleInvoice = new TDxVehicleSaleInvoice();
        TDxRecordEntity veinfo = null;
        if ("1".equals(tDxHttpLog.getDataType())) {
            veinfo = new TDxRecordEntity();
        }
        if ("2".equals(tDxHttpLog.getDataType())) {
            veinfo = new TDxSaleRecordInvoiceJobEntity();

        }
        veinfo.setInvoiceCode(info.getInvoiceCode());
        veinfo.setInvoiceNo(info.getInvoiceNo());
        veinfo.setInvoiceType(info.getInvoiceType());
        veinfo.setGfName(info.getBuyerName());
        veinfo.setInvoiceDate(new SimpleDateFormat("yyyy-MM-dd").parse(info.getInvoiceDate()));
        if (StringUtils.isBlank(info.getBuyerIdNum())) {
            vehicleSaleInvoice.setBuyerIdNum("");
        } else {
            vehicleSaleInvoice.setBuyerIdNum(info.getBuyerIdNum());
        }

        if (StringUtils.isBlank(info.getVehicleType())) {
            vehicleSaleInvoice.setVehicleType("");
        } else {
            vehicleSaleInvoice.setVehicleType(info.getVehicleType());
        }
        if (StringUtils.isBlank(info.getFactoryModel())) {
            vehicleSaleInvoice.setFactoryModel("");
        } else {
            vehicleSaleInvoice.setFactoryModel(info.getFactoryModel());
        }

        if (StringUtils.isBlank(info.getVehicleNo())) {
            vehicleSaleInvoice.setVehicleNo("");
        } else {
            vehicleSaleInvoice.setVehicleNo(info.getVehicleNo());
        }
        veinfo.setTotalAmount(new BigDecimal(info.getTotalAmount()));
        veinfo.setXfName(info.getSellerName());
        veinfo.setXfTaxNo(info.getSellerIdNum());
        veinfo.setGfTaxNo(info.getBuyerIdNum());
        veinfo.setGfAddressAndPhone(info.getBuyerAddress());
        if (StringUtils.isBlank(info.getSellerPhone())) {
            vehicleSaleInvoice.setPhone("");
        } else {
            vehicleSaleInvoice.setPhone(info.getSellerPhone());
        }
        if (StringUtils.isNotEmpty(info.getSellerAddress()) && StringUtils.isNotEmpty(info.getSellerPhone())) {
            veinfo.setXfAddressAndPhone(info.getSellerAddress());
        }
        vehicleSaleInvoice.setGfPhone(info.getBuyerPhone());
        veinfo.setRemark(info.getRemark());
        veinfo.setDkTaxno(info.getDkTaxno());
        veinfo.setDkTaxname(info.getDkTaxname());
        veinfo.setDkStatus(info.getDkStatus());
        veinfo.setInvoiceAmount(new BigDecimal(info.getTotalAmount()));
        // 二手车明细表添加字段
        vehicleSaleInvoice.setPlateNo(info.getPlateNo());
        vehicleSaleInvoice.setRegistrationNo(info.getCertificateNo());
        vehicleSaleInvoice.setVehicleAdminOffice(info.getVehicleAdminOffice());
        vehicleSaleInvoice.setAuctionUnit(info.getAuctionUnit());
        vehicleSaleInvoice.setAuctionAddress(info.getAuctionAddress());
        vehicleSaleInvoice.setAuctionTaxNo(info.getAuctionTaxno());
        vehicleSaleInvoice.setAuctionBank(info.getAuctionBank());
        vehicleSaleInvoice.setAuctionPhone(info.getAuctionPhone());
        vehicleSaleInvoice.setCarMarket(info.getCarMarket());
        vehicleSaleInvoice.setCarMarketTaxNo(info.getCarMarketTaxno());
        vehicleSaleInvoice.setCarMarketAddress(info.getCarMarketAddress());
        vehicleSaleInvoice.setCarMarketBank(info.getCarMarketBank());
        vehicleSaleInvoice.setCarMarketPhone(info.getCarMarketPhone());
        veinfo.setInvoiceStatus(info.getInvoiceStatus());
        //如果发票状态是 80-红字发票待确认
        if(FpztEnum.HZDQR.getFpztDm().equals(info.getInvoiceStatus())){
            veinfo.setLqHzsdbs("Y");
        }
        veinfo.setRzhYesorno("0");

        veinfo.setSourceSystem("2");
        veinfo.setCreateDate(new Date());
        Map<String, Object> map = new HashMap<>(2);
        map.put("vehicleSaleInvoice", vehicleSaleInvoice);
        map.put("veinfo", veinfo);
        return map;
    }

    public Map<String, Object> getVehicleInfo(VehicleInvoiceModel info, TDxHttpLogInvoiceDown tDxHttpLog)
        throws ParseException {

        TDxVehicleSaleInvoice vehicleSaleInvoice = new TDxVehicleSaleInvoice();
        TDxRecordEntity veinfo = null;
        if ("1".equals(tDxHttpLog.getDataType())) {
            veinfo = new TDxRecordEntity();
        }
        if ("2".equals(tDxHttpLog.getDataType())) {
            veinfo = new TDxSaleRecordInvoiceJobEntity();
        }
        veinfo.setInvoiceCode(info.getInvoiceCode());
        veinfo.setInvoiceNo(info.getInvoiceNo());
        veinfo.setInvoiceType(info.getInvoiceType());
        veinfo.setGfName(info.getBuyerName());
        veinfo.setInvoiceDate(new SimpleDateFormat("yyyy-MM-dd").parse(info.getInvoiceDate()));
        if (StringUtils.isBlank(info.getBuyerIdNum())) {
            vehicleSaleInvoice.setBuyerIdNum("");
        } else {
            vehicleSaleInvoice.setBuyerIdNum(info.getBuyerIdNum());
        }

        if (StringUtils.isBlank(info.getVehicleType())) {
            vehicleSaleInvoice.setVehicleType("");
        } else {
            vehicleSaleInvoice.setVehicleType(info.getVehicleType());
        }
        if (StringUtils.isBlank(info.getFactoryModel())) {
            vehicleSaleInvoice.setFactoryModel("");
        } else {
            vehicleSaleInvoice.setFactoryModel(info.getFactoryModel());
        }
        if (StringUtils.isBlank(info.getProductPlace())) {
            vehicleSaleInvoice.setProductPlace("");
        } else {
            vehicleSaleInvoice.setProductPlace(info.getProductPlace());
        }
        if (StringUtils.isBlank(info.getCertificate())) {
            vehicleSaleInvoice.setCertificate("");
        } else {
            vehicleSaleInvoice.setCertificate(info.getCertificate());
        }
        if (StringUtils.isBlank(info.getCertificateImport())) {
            vehicleSaleInvoice.setCertificateImport("");
        } else {
            vehicleSaleInvoice.setCertificateImport(info.getCertificateImport());
        }
        if (StringUtils.isBlank(info.getInspectionNum())) {
            vehicleSaleInvoice.setInspectionNum("");
        } else {
            vehicleSaleInvoice.setInspectionNum(info.getInspectionNum());
        }
        if (StringUtils.isBlank(info.getEngineNo())) {
            vehicleSaleInvoice.setEngineNo("");
        } else {
            vehicleSaleInvoice.setEngineNo(info.getEngineNo());
        }
        if (StringUtils.isBlank(info.getVehicleNo())) {
            vehicleSaleInvoice.setVehicleNo("");
        } else {
            vehicleSaleInvoice.setVehicleNo(info.getVehicleNo());
        }
        veinfo.setTotalAmount(new BigDecimal(info.getTotalAmount()));
        veinfo.setXfName(info.getSalerName());
        veinfo.setXfTaxNo(info.getSalerTaxno());
        veinfo.setGfTaxNo(info.getBuyerTaxNo());

        if (StringUtils.isBlank(info.getSalerPhone())) {
            vehicleSaleInvoice.setPhone("");
        } else {
            vehicleSaleInvoice.setPhone(info.getSalerPhone());
        }
        if (StringUtils.isNotEmpty(info.getSalerAddress()) && StringUtils.isNotEmpty(info.getSalerPhone())) {
            veinfo.setXfAddressAndPhone(info.getSalerAddress() + info.getSalerPhone());
        }
        if (StringUtils.isNotEmpty(info.getSalerBank()) && StringUtils.isNotEmpty(info.getSalerAcount())) {
            veinfo.setXfBankAndNo(info.getSalerBank() + info.getSalerAcount());
        }
        vehicleSaleInvoice.setTaxRate(info.getTaxRate());
        veinfo.setTaxAmount(new BigDecimal(info.getTaxAmount()));
        if (StringUtils.isBlank(info.getTaxBureauCode())) {
            vehicleSaleInvoice.setTaxBureauCode("");
        } else {
            vehicleSaleInvoice.setTaxBureauCode(info.getTaxBureauCode());
        }
        if (StringUtils.isBlank(info.getTaxBureauName())) {
            vehicleSaleInvoice.setTaxBureauName("");
        } else {
            vehicleSaleInvoice.setTaxBureauName(info.getTaxBureauName());
        }
        veinfo.setInvoiceAmount(new BigDecimal(info.getTotalAmount()));
        if (StringUtils.isBlank(info.getTaxRecords())) {
            vehicleSaleInvoice.setTaxRecords("");
        } else {
            vehicleSaleInvoice.setTaxRecords(info.getTaxRecords());
        }
        if (StringUtils.isBlank(info.getTonnage())) {
            vehicleSaleInvoice.setTonnage("");
        } else {
            vehicleSaleInvoice.setTonnage(info.getTonnage());
        }
        if (StringUtils.isBlank(info.getLimitPeople())) {
            vehicleSaleInvoice.setLimitPeople("");
        } else {
            vehicleSaleInvoice.setLimitPeople(info.getLimitPeople());
        }
        veinfo.setInvoiceStatus(info.getInvoiceStatus());
        //如果发票状态是 80-红字发票待确认
        if(FpztEnum.HZDQR.getFpztDm().equals(info.getInvoiceStatus())){
            veinfo.setLqHzsdbs("Y");
        }
        veinfo.setRzhYesorno("0");
        veinfo.setDkTaxno(info.getDkTaxno());
        veinfo.setDkTaxname(info.getDkTaxname());
        veinfo.setDkStatus(info.getDkStatus());
        veinfo.setSourceSystem("2");
        veinfo.setCreateDate(new Date());
        Map<String, Object> map = new HashMap<>(2);
        map.put("vehicleSaleInvoice", vehicleSaleInvoice);
        map.put("veinfo", veinfo);
        return map;
    }

    /**
     * 解析专，电，普，卷
     *
     * @param logid
     * @param tDxHttpLog
     * @param dataJson
     * @param db
     */
    private void parseInvoice(Long logid, TDxHttpLogInvoiceDown tDxHttpLog, String dataJson, String db) {
        JSONObject json = JSONObject.parseObject(dataJson);
        JSONArray records = json.getJSONArray("invoices");
        String total;
        try {
            List<RecordInvoiceDownModel> invoicesList = records.toJavaList(RecordInvoiceDownModel.class);
            total = invoicesList.size() + "";
            for (RecordInvoiceDownModel dataPlatformInvoiceInfo : invoicesList) {
                String invoiceCode = dataPlatformInvoiceInfo.getInvoiceCode();
                String invoiceNo = dataPlatformInvoiceInfo.getInvoiceNo();
                //判断发票状态是否 80-红字发票待确认
                if(FpztEnum.HZDQR.getFpztDm().equals(dataPlatformInvoiceInfo.getInvoiceStatus())){
                    dataPlatformInvoiceInfo.setLqHzsdbs("Y");
                }

                // 判断库里有无 有-更新 无-插入
                DynamicContextHolder.push(db + DbConstant.BUSINESS_READ);
                TDxRecordInvoice invoice = null;
                if ("1".equals(tDxHttpLog.getDataType())) {
                    invoice = tDxRecordInvoiceJobDao.findInvoiceByCodeAndNo(invoiceCode, invoiceNo);
                }
                if ("2".equals(tDxHttpLog.getDataType())) {
                    invoice = tDxRecordInvoiceJobDao.findSaleInvoiceByCodeAndNo(invoiceCode, invoiceNo);
                }
                if (invoice != null) {
                    if ("1".equals(invoice.getSourceSystem())
                        || !invoice.getInvoiceStatus().equals(dataPlatformInvoiceInfo.getInvoiceStatus())) {
                        // 更新
                        if ("1".equals(invoice.getSourceSystem()) && "0".equals(invoice.getCollectStatus())) {
                            dataPlatformInvoiceInfo.setCollectStatus("1");
                            dataPlatformInvoiceInfo.setCollectFrom("1");
                            dataPlatformInvoiceInfo.setCollectDate(new Date());
                            dataPlatformInvoiceInfo.setPoolStatus("1");
                            dataPlatformInvoiceInfo.setInPoolReason("数据重复");
                        }
                        if (!invoice.getInvoiceStatus().equals(dataPlatformInvoiceInfo.getInvoiceStatus())) {
                            dataPlatformInvoiceInfo.setStatusUpdateDate(new Date());
                        }
                        updateInvoiceAndDetail(dataPlatformInvoiceInfo, db, tDxHttpLog);

                    } else {
                        // 不做更新，记录日志表
                        insertDataPlatformLog(dataPlatformInvoiceInfo, db);
                    }
                } else {
                    // 插入
                    dataPlatformInvoiceInfo.setCompany(tDxHttpLog.getCompany());
                    insertInvoiceAndDetail(dataPlatformInvoiceInfo, db, tDxHttpLog);
                }
            }

        } catch (Exception e) {
            tDxHttpLog.setStatus("2");
            tDxHttpLog.setTotal("0");
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            coreInvoiceDownDao.updateHttpLogById(tDxHttpLog);
           log.info("业务处理异常：{}", e);
            return;
        }
        tDxHttpLog.setStatus("1");
        tDxHttpLog.setTotal(total);
        DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
        coreInvoiceDownDao.updateHttpLogById(tDxHttpLog);
    }

    private void updateNotParseHttpLogsStatus(List<TDxHttpLogInvoiceDown> logs) {
        coreInvoiceDownDao.updateNotParseHttpLogsStatus(logs);
    }

    private List<TDxHttpLogInvoiceDown> getNotParseHttpLogs(String taxno) {
        return coreInvoiceDownDao.getNotParseHttpLogs(taxno);
    }

    /**
     * 更新数据库数据
     *
     * @param invoice
     *            发票信息
     * @param db
     * @param tDxHttpLog
     */
    private void updateInvoiceAndDetail(RecordInvoiceDownModel invoice, String db, TDxHttpLogInvoiceDown tDxHttpLog) {
        String invoiceCode = invoice.getInvoiceCode();
        String invoiceNo = invoice.getInvoiceNo();
        String uuid = invoiceCode + invoiceNo;
        List<RecordInvoiceDetailModel> detailList = invoice.getDetailList();
        if (detailList != null && detailList.size() > 0) {
            DynamicContextHolder.push(db + DbConstant.DETAIL_WRITE);
            if ("1".equals(tDxHttpLog.getDataType())) {
                coreInvoiceDownDao.delDetailIncome(invoiceCode + invoiceNo);
                for (RecordInvoiceDetailModel invoiceDetailInfo : detailList) {
                    invoiceDetailInfo.setInvoiceCode(invoiceCode);
                    invoiceDetailInfo.setInvoiceNo(invoiceNo);
                    invoiceDetailInfo.setUuid(uuid);
                    invoiceDownDetaiInsertDao.insert(invoiceDetailInfo);
                }
            }
            if ("2".equals(tDxHttpLog.getDataType())) {
                coreInvoiceDownDao.delDetailSales(invoiceCode + invoiceNo);
                for (RecordInvoiceDetailModel invoiceDetailInfo : detailList) {
                    invoiceDetailInfo.setInvoiceCode(invoiceCode);
                    invoiceDetailInfo.setInvoiceNo(invoiceNo);
                    invoiceDetailInfo.setUuid(uuid);
                    RecordInvoiceSaleDetailModel saleModel = new RecordInvoiceSaleDetailModel();
                    saleModel = exchange(invoiceDetailInfo, saleModel);
                    invoiceDownDetaiSaleInsertDao.insert(saleModel);
                }
            }

            if ("1".equals(tDxHttpLog.getDataType())) {
                DynamicContextHolder.push(db + DbConstant.DETAIL_READ);
                int countDetail = coreInvoiceDownDao.getDetailCount(invoiceCode + invoiceNo, "t_dx_record_invoice_detail");
                if (countDetail > 0) {
                    invoice.setDetailYesorno("1");
                } else {
                    invoice.setDetailYesorno("0");
                }
                DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
                coreInvoiceDownDao.updateRecordInvoice(invoice);
            }
            if ("2".equals(tDxHttpLog.getDataType())) {
                DynamicContextHolder.push(db + DbConstant.DETAIL_READ);
                int countDetail =
                    coreInvoiceDownDao.getDetailCount(invoiceCode + invoiceNo, "t_dx_record_invoice_detail_sales");
                if (countDetail > 0) {
                    invoice.setDetailYesorno("1");
                } else {
                    invoice.setDetailYesorno("0");
                }
                DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
                if (invoice.getBuyerName() != null) {
                    invoice.setBuyerName(changeBrackets(invoice.getBuyerName()));
                }
                coreInvoiceDownDao.updateSaleRecordInvoice(invoice);
            }

        }
    }

    private RecordInvoiceSaleDetailModel exchange(RecordInvoiceDetailModel invoiceDetailInfo,
        RecordInvoiceSaleDetailModel saleModel) {
        String json = JSON.toJSONString(invoiceDetailInfo);
        saleModel = JSONObject.parseObject(json, RecordInvoiceSaleDetailModel.class);
        return saleModel;
    }

    public String changeBrackets(String paramString) {
        return paramString.replace("（", "(").replace("(", "(").replace("）", ")").replace(")", ")");
    }

    private void insertDataPlatformLog(RecordInvoiceDownModel dataPlatformInvoiceInfo, String db) {
        // 插入日志信息
        DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
        DataPlatformInvoiceLog data = new DataPlatformInvoiceLog();
        data.setInvoiceCode(dataPlatformInvoiceInfo.getInvoiceCode());
        data.setInvoiceNo(dataPlatformInvoiceInfo.getInvoiceNo());
        data.setCreateDate(new Date());
        data.setMessage("数据重复");
        data.setSystemSource("2");
        dataPlatformFailRecordDao.insert(data);
    }

    /**
     * 插入数据
     *
     * @param dataPlatformInvoiceInfo
     *            日志信息
     * @param db
     * @param tDxHttpLog
     */
    private void insertInvoiceAndDetail(RecordInvoiceDownModel dataPlatformInvoiceInfo, String db,
        TDxHttpLogInvoiceDown tDxHttpLog) throws ParseException {
        String invoiceCode = dataPlatformInvoiceInfo.getInvoiceCode();
        String invoiceNo = dataPlatformInvoiceInfo.getInvoiceNo();
        dataPlatformInvoiceInfo.setUuid(invoiceCode + invoiceNo);
        DynamicContextHolder.push(db + DbConstant.DETAIL_WRITE);
        // 插入明细
        List<RecordInvoiceDetailModel> detailList = dataPlatformInvoiceInfo.getDetailList();
        // 进项发票入库
        if ("1".equals(tDxHttpLog.getDataType())) {
            for (RecordInvoiceDetailModel dataPlatformInvoiceDetailInfo : detailList) {
                dataPlatformInvoiceDetailInfo.setUuid(invoiceCode + invoiceNo);
                dataPlatformInvoiceDetailInfo.setInvoiceCode(invoiceCode);
                dataPlatformInvoiceDetailInfo.setInvoiceNo(invoiceNo);
                invoiceDownDetaiInsertDao.insert(dataPlatformInvoiceDetailInfo);
            }
        }
        if ("2".equals(tDxHttpLog.getDataType())) {
            for (RecordInvoiceDetailModel dataPlatformInvoiceDetailInfo : detailList) {
                dataPlatformInvoiceDetailInfo.setUuid(invoiceCode + invoiceNo);
                dataPlatformInvoiceDetailInfo.setInvoiceCode(invoiceCode);
                dataPlatformInvoiceDetailInfo.setInvoiceNo(invoiceNo);
                RecordInvoiceSaleDetailModel saleModel = new RecordInvoiceSaleDetailModel();
                saleModel = exchange(dataPlatformInvoiceDetailInfo, saleModel);
                invoiceDownDetaiSaleInsertDao.insert(saleModel);
            }
        }

        // 进项发票入库
        if ("1".equals(tDxHttpLog.getDataType())) {
            int countDetail = coreInvoiceDownDao.getDetailCount(invoiceCode + invoiceNo, "t_dx_record_invoice_detail");
            if (countDetail > 0) {
                dataPlatformInvoiceInfo.setDetailYesorno("1");
            } else {
                dataPlatformInvoiceInfo.setDetailYesorno("0");
            }
            DataPlatformRecordEntity invoice;
            invoice = (DataPlatformRecordEntity)getInvoiceInfo(dataPlatformInvoiceInfo, tDxHttpLog.getDataType());
            invoice.setCompany(dataPlatformInvoiceInfo.getCompany());
            //记录通道来源
            invoice.setTdly("1");
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            dataPlatformRecordDao.insert(invoice);
        }
        if ("2".equals(tDxHttpLog.getDataType())) {
            int countDetail =
                coreInvoiceDownDao.getDetailCount(invoiceCode + invoiceNo, "t_dx_record_invoice_detail_sales");
            if (countDetail > 0) {
                dataPlatformInvoiceInfo.setDetailYesorno("1");
            } else {
                dataPlatformInvoiceInfo.setDetailYesorno("0");
            }
            DataPlatformSaleRecordEntity invoice;
            invoice = (DataPlatformSaleRecordEntity)getInvoiceInfo(dataPlatformInvoiceInfo, tDxHttpLog.getDataType());
            invoice.setCompany(dataPlatformInvoiceInfo.getCompany());
            //记录通道来源
            invoice.setTdly("1");
            if (invoice!=null&&invoice.getGfName() != null) {
                invoice.setGfName(changeBrackets(invoice.getGfName()));
            }
            DynamicContextHolder.push(db + DbConstant.BUSINESS_WRITE);
            dataPlatformSaleRecordDao.insert(invoice);
        }
    }

    /**
     * 转换实体
     *
     * @param info
     *            发票信息
     * @param subject
     * @return 返回
     */
    private DataPlatformEntity getInvoiceInfo(RecordInvoiceDownModel info, String subject) throws ParseException {
        DataPlatformEntity invoice = null;
        if ("1".equals(subject)) {
            invoice = new DataPlatformRecordEntity();
        }
        if ("2".equals(subject)) {
            invoice = new DataPlatformSaleRecordEntity();
        }
        // 发票代码
        invoice.setInvoiceCode(info.getInvoiceCode());
        // 发票号码
        invoice.setInvoiceNo(info.getInvoiceNo());
        // 发票类型
        invoice.setInvoiceType(info.getInvoiceType());
        // 购方名称
        invoice.setGfName(info.getBuyerName());
        // 购方税号
        invoice.setGfTaxNo(info.getBuyerTaxNo());
        // 购方地址、电话
        invoice.setGfAddressAndPhone(info.getBuyerAddressPhone());
        // 购方开户行及账号
        invoice.setGfBankAndNo(info.getBuyerAcount());
        // 销方名称
        invoice.setXfName(info.getSalerName());
        // 销方税号
        invoice.setXfTaxNo(info.getSalerTaxNo());
        // 销方地址、电话
        invoice.setXfAddressAndPhone(info.getSalerAddressPhone());
        // 销方开户行及账号
        invoice.setXfBankAndNo(info.getSalerAcount());
        // 开票日期
        invoice.setInvoiceDate(new SimpleDateFormat("yyyy-MM-dd").parse(info.getInvoiceDate()));

        // 备注
        invoice.setRemark(info.getRemark());
        // 发票状态
        invoice.setInvoiceStatus(info.getInvoiceStatus());
        //如果发票状态是 80-红字发票待确认
        if(FpztEnum.HZDQR.getFpztDm().equals(info.getInvoiceStatus())){
            invoice.setLqHzsdbs("Y");
        }
        // 是否代办退税
        invoice.setSfdbts(null);

        if (info.getInvoiceAmount() != null && !"".equals(info.getInvoiceAmount())) {
            // 发票金额
            invoice.setInvoiceAmount(new BigDecimal(info.getInvoiceAmount()));
        }
        if (info.getTaxAmount() != null && !"".equals(info.getTaxAmount())) {
            // 发票税额
            invoice.setTaxAmount(new BigDecimal(info.getTaxAmount()));
        }
        if (info.getTotalAmount() != null && !"".equals(info.getTotalAmount())) {
            // 价税合计
            invoice.setTotalAmount(new BigDecimal(info.getTotalAmount()));
        }

        // 校验码
        if (info.getCheckCode() == null || "".equals(info.getCheckCode())) {
            invoice.setCheckCode("");
        } else {
            invoice.setCheckCode(info.getCheckCode());
        }
        invoice.setAuthStatus("0");
        invoice.setDetailYesorno(info.getDetailYesorno());
        invoice.setValid("1");
        invoice.setUuid(info.getUuid());
        invoice.setCreateDate(new Date());
        // 新增底账字段
        invoice.setPayee(info.getPayee());
        invoice.setReviewer(info.getReviewer());
        invoice.setMachinecode(info.getJqbm());
        invoice.setPrintor(info.getInvoicer());
        invoice.setMw(info.getMw());
        invoice.setJdhm(info.getJdhm());
        invoice.setDkTaxno(info.getDkTaxno());
        invoice.setDkTaxname(info.getDkTaxname());
        invoice.setDkStatus(info.getDkStatus());
        invoice.setSourceSystem("2");
        // 第一次插入添加票池采集字段
        invoice.setCollectStatus("1");
        invoice.setCollectFrom("1");
        invoice.setCollectDate(new Date());
        invoice.setPoolStatus("0");
        return invoice;
    }
}
