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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.MathUtil;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.core.dao.TDxRecordInvoiceDao;
import com.dxhy.core.entity.TDxRecordInvoice;
import com.dxhy.core.job.entity.TDxRecordInvoiceDetail;
import com.dxhy.core.job.entity.TDxRecordInvoiceStatistics;
import com.dxhy.core.job.entity.TDxVehicleSaleInvoice;
import com.dxhy.core.service.singletable.CoreInvoiceStatisticsService;
import com.dxhy.core.service.singletable.CoreSaveInvoiceInfoService;
import com.dxhy.core.service.singletable.IInvoiceDetail;
import com.dxhy.core.service.singletable.IJdcService;

import lombok.extern.slf4j.Slf4j;

/**
 * 保存发票查验结果业务处理实现类
 *
 * @author user @date(创建日期)：2019年5月8日
 */

@Service("coreSaveInvoiceInfoService")
@Slf4j
@SuppressWarnings("AlibabaUndefineMagicConstant")
public class CoreSaveInvoiceInfoServiceImpl extends MpBaseServiceImpl<TDxRecordInvoiceDao, TDxRecordInvoice>
    implements CoreSaveInvoiceInfoService {

    @Resource
    private IJdcService jdcService;

    @Resource
    private IInvoiceDetail invoiceDetail;

    @Resource
    private CoreInvoiceStatisticsService coreInvoiceStatisticsService;

    /**
     * 批量操作的大小
     */
    private final int batchSize = 500;

    @Override
    public void saveQueryInvoiceResult(JSONObject queryInvoiceResult, String dbName) {

        // 获取机动车表信息
        TDxVehicleSaleInvoice vehicleSaleInvoice = getVehicleSaleInvoice(queryInvoiceResult);
        // 底账明细表
        List<TDxRecordInvoiceDetail> recordInvoiceDetail = getRecordInvoiceDetail(queryInvoiceResult);
        // 税率统计表
        List<TDxRecordInvoiceStatistics> invoiceStatistics = getInvoiceStatistics(queryInvoiceResult);

        // 更新底账表的明细标志为1，已存在明细
        String invoiceCode = queryInvoiceResult.getString("invoiceCode");
        String invoiceNo = queryInvoiceResult.getString("invoiceNo");
        String uuid = invoiceCode + invoiceNo;

        // 机动车票
        if (vehicleSaleInvoice != null) {
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
            this.saveVehicleSaleInvoice(vehicleSaleInvoice, invoiceStatistics, uuid, invoiceCode, invoiceNo,
                queryInvoiceResult);
        }

        // 其它票，保存底账明细表数据
        if (recordInvoiceDetail != null && recordInvoiceDetail.size() > 0) {

            // 保存底账明细表数据
            DynamicContextHolder.push(dbName + DbConstant.DETAIL_WRITE);
            // 删除已存在的数据，防止数据重复
            QueryWrapper<TDxRecordInvoiceDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uuid", uuid);
            invoiceDetail.remove(queryWrapper);
            // 保存新的明细
            invoiceDetail.saveBatch(recordInvoiceDetail, batchSize);

            // 保存税率表，更新明细存在标志
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
            this.saveVehicleSaleInvoice(null, invoiceStatistics, uuid, invoiceCode, invoiceNo, queryInvoiceResult);

        }
    }

    /**
     * 根据查验结果获取税率统计表对象
     *
     * @param queryInvoiceResult
     * @return
     *
     */
    private List<TDxRecordInvoiceStatistics> getInvoiceStatistics(JSONObject queryInvoiceResult) {
        List<TDxRecordInvoiceStatistics> invoiceStatisticsList = new ArrayList<>();
        String invoiceType = queryInvoiceResult.getString("invoiceType");
        if (FplxEnum.JDC.getFplxDm().equals(invoiceType)) {
            TDxRecordInvoiceStatistics invoiceStatistics = new TDxRecordInvoiceStatistics();
            invoiceStatistics.setCreateDate(DateUtils.getSqlDateLong());
            invoiceStatistics.setInvoiceCode(queryInvoiceResult.getString("invoiceCode"));
            invoiceStatistics.setInvoiceNo(queryInvoiceResult.getString("invoiceNo"));
            invoiceStatistics.setDetailAmount(queryInvoiceResult.getBigDecimal("invoiceAmount"));
//            invoiceStatistics.setTaxRate(queryInvoiceResult.getBigDecimal("taxRate"));
//            invoiceStatistics.setTaxAmount(queryInvoiceResult.getBigDecimal("taxAmount"));
            String taxRate = queryInvoiceResult.getString("taxRate");
            log.info("taxRate={}",taxRate);
            if(StringUtils.isNotEmpty(taxRate)) {
                if (taxRate.contains("%")) {
                    taxRate = taxRate.replace("%", "");
                }
                if("免税".equals(taxRate)){
                    invoiceStatistics.setTaxRate(new BigDecimal("0"));
                }else {
                    invoiceStatistics.setTaxRate(new BigDecimal(taxRate));
                }
            }
            String amount = queryInvoiceResult.getString("taxAmount");
            if(StringUtils.isNotEmpty(amount)){
                try {
                    invoiceStatistics.setTaxAmount(queryInvoiceResult.getBigDecimal("taxAmount"));
                } catch (Exception e) {
                    invoiceStatistics.setTaxAmount(new BigDecimal("0"));
                }
            }
            String resultString = queryInvoiceResult.getString("totalAmount");
            if(StringUtils.isNotEmpty(resultString)){
                invoiceStatistics.setTotalAmount(queryInvoiceResult.getBigDecimal("totalAmount"));
            }
            invoiceStatisticsList.add(invoiceStatistics);
        } else {
            if (queryInvoiceResult.containsKey("detailList")) {
                JSONArray dataArray = queryInvoiceResult.getJSONArray("detailList");
                if (dataArray != null && dataArray.size() > 0) {
                    // 同一张发票相同税率需要滤重，否则保存会报错
                    Map<String, String> slvMap = new HashMap<>(16);
                    for (int i = 0; i < dataArray.size(); i++) {
                        JSONObject invoiceDetailQuery = dataArray.getJSONObject(i);
                        String taxRate = invoiceDetailQuery.getString("taxRate");
                        if(StringUtils.isEmpty(taxRate)){
                            taxRate = "";
                        }
                        String slvPri = queryInvoiceResult.getString("invoiceCode") + queryInvoiceResult.getString("invoiceNo") + taxRate;
                        if (!slvMap.containsKey(slvPri)) {
                            slvMap.put(slvPri, slvPri);
                            TDxRecordInvoiceStatistics invoiceStatistics = new TDxRecordInvoiceStatistics();
                            invoiceStatistics.setCreateDate(DateUtils.getSqlDateLong());
                            invoiceStatistics.setInvoiceCode(queryInvoiceResult.getString("invoiceCode"));
                            invoiceStatistics.setInvoiceNo(queryInvoiceResult.getString("invoiceNo"));
                            if(StringUtils.isNotBlank(taxRate)){
                                try {
                                    invoiceStatistics.setTaxRate(invoiceDetailQuery.getBigDecimal("taxRate"));
                                } catch (Exception e) {
                                    invoiceStatistics.setTaxRate(new BigDecimal("0"));
                                }
                            }
                            String detailAmount = invoiceDetailQuery.getString("detailAmount");
                            String taxAmount = invoiceDetailQuery.getString("taxAmount");
                            if(StringUtils.isNotBlank(detailAmount)){
                                invoiceStatistics.setDetailAmount(invoiceDetailQuery.getBigDecimal("detailAmount"));
                            }
                            if(StringUtils.isNotBlank(taxAmount)){
                                try {
                                    invoiceStatistics.setTaxAmount(invoiceDetailQuery.getBigDecimal("taxAmount"));
                                } catch (Exception e) {
                                    invoiceStatistics.setTaxAmount(new BigDecimal("0"));
                                }
                            }
                            if (StringUtils.isNotBlank(detailAmount) && StringUtils.isNotBlank(taxAmount)) {
                                try {
                                    detailAmount = new BigDecimal(detailAmount).toPlainString();
                                } catch (Exception e) {
                                    detailAmount = "0";
                                }
                                try {
                                    taxAmount = new BigDecimal(taxAmount).toPlainString();
                                } catch (Exception e) {
                                    taxAmount = "0";
                                }
                                invoiceStatistics.setTotalAmount(new BigDecimal(MathUtil.add(detailAmount, taxAmount)));
                            }
                            invoiceStatisticsList.add(invoiceStatistics);
                        }
                    }
                }
            }
        }

        return invoiceStatisticsList;
    }

    /**
     * 保存明细数据
     *
     * @param queryInvoiceResult
     * @param vehicleSaleInvoice
     *            机动车
     * @param invoiceStatistics
     *            抵账统计
     * @param uuid
     *            uuid
     * @param invoiceNo
     *            发票号码
     * @param invoiceCode
     *            发票代码
     *
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveVehicleSaleInvoice(TDxVehicleSaleInvoice vehicleSaleInvoice,
        List<TDxRecordInvoiceStatistics> invoiceStatistics, String uuid, String invoiceCode, String invoiceNo,
        JSONObject queryInvoiceResult) {
        if (vehicleSaleInvoice != null) {
            // 删除已存在的数据，防止数据重复
            QueryWrapper<TDxVehicleSaleInvoice> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uuid", uuid);
            jdcService.remove(queryWrapper);
            // 保存机动车表数据
            jdcService.save(vehicleSaleInvoice);
        }
        // 删除已存在的数据，防止数据重复
        QueryWrapper<TDxRecordInvoiceStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invoice_code", invoiceCode);
        queryWrapper.eq("invoice_no", invoiceNo);
        coreInvoiceStatisticsService.remove(queryWrapper);
        // 保存税率统计表
        coreInvoiceStatisticsService.saveBatch(invoiceStatistics);
        // 更新底账表明细存在标志
        TDxRecordInvoice recordInvoice = new TDxRecordInvoice();
        recordInvoice.setDetailYesorno("1");
        recordInvoice.setTotalAmount(new BigDecimal(queryInvoiceResult.getString("totalAmount")));
        recordInvoice.setGfName(queryInvoiceResult.getString("buyerName"));
        recordInvoice.setGfAddressAndPhone(queryInvoiceResult.getString("buyerAddressPhone"));
        recordInvoice.setGfBankAndNo(queryInvoiceResult.getString("buyerAccount"));
        recordInvoice.setXfAddressAndPhone(queryInvoiceResult.getString("salerAddressPhone"));
        recordInvoice.setXfBankAndNo(queryInvoiceResult.getString("salerAccount"));
        recordInvoice.setRemark(queryInvoiceResult.getString("remark"));
        UpdateWrapper<TDxRecordInvoice> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("uuid", uuid);
        super.update(recordInvoice, updateWrapper);
    }

    /**
     * 根据查验结果转换发票明细表对象
     *
     * @param queryInvoiceResult
     * @return
     *
     */
    private List<TDxRecordInvoiceDetail> 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<TDxRecordInvoiceDetail> invoiceDetailList = new ArrayList<>(dataArray.size());
                for (int i = 0; i < dataArray.size(); i++) {
                    JSONObject invoiceDetailQuery = dataArray.getJSONObject(i);
                    TDxRecordInvoiceDetail invoiceDetailEntity = new TDxRecordInvoiceDetail();
                    invoiceDetailEntity.setUuid(uuid);
                    invoiceDetailEntity.setInvoiceCode(invoiceCode);
                    invoiceDetailEntity.setInvoiceNo(invoiceNo);
                    invoiceDetailEntity.setDetailNo(invoiceDetailQuery.getString("detailNo"));
                    invoiceDetailEntity.setGoodsName(invoiceDetailQuery.getString("goodsName"));
                    invoiceDetailEntity.setModel(invoiceDetailQuery.getString("specificationModel"));
                    invoiceDetailEntity.setUnit(invoiceDetailQuery.getString("unit"));
                    invoiceDetailEntity.setNum(invoiceDetailQuery.getString("num"));
                    invoiceDetailEntity.setUnitPrice(invoiceDetailQuery.getString("unitPrice"));
                    invoiceDetailEntity.setDetailAmount(invoiceDetailQuery.getString("detailAmount"));
                    invoiceDetailEntity.setTaxRate(invoiceDetailQuery.getString("taxRate"));
                    invoiceDetailEntity.setTaxAmount(invoiceDetailQuery.getString("taxAmount"));
                    if (FplxEnum.TXF.getFplxDm().equals(invoiceType)) {
                        // 通行费发票
                        invoiceDetailEntity.setCph(invoiceDetailQuery.getString("cph"));
                        invoiceDetailEntity.setLx(invoiceDetailQuery.getString("lx"));
                        invoiceDetailEntity.setTxrqq(invoiceDetailQuery.getString("txrqq"));
                        invoiceDetailEntity.setTxrqz(invoiceDetailQuery.getString("txrqz"));
                    }
                    invoiceDetailList.add(invoiceDetailEntity);
                }
                return invoiceDetailList;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 根据查验结果转换底账机动车表明细
     *
     * @param queryInvoiceResult
     * @return
     *
     */
    private TDxVehicleSaleInvoice getVehicleSaleInvoice(JSONObject queryInvoiceResult) {
        String invoiceType = queryInvoiceResult.getString("invoiceType");
        if (FplxEnum.JDC.getFplxDm().equals(invoiceType)) {
            String invoiceCode = queryInvoiceResult.getString("invoiceCode");
            String invoiceNo = queryInvoiceResult.getString("invoiceNo");
            String uuid = invoiceCode + invoiceNo;

            TDxVehicleSaleInvoice vehicleSaleInvoice = new TDxVehicleSaleInvoice();
            vehicleSaleInvoice.setUuid(uuid);
            vehicleSaleInvoice.setBuyerIdNum(queryInvoiceResult.getString("buyerIDNum"));
            vehicleSaleInvoice.setVehicleType(queryInvoiceResult.getString("vehicleType"));
            vehicleSaleInvoice.setFactoryModel(queryInvoiceResult.getString("factoryModel"));
            vehicleSaleInvoice.setProductPlace(queryInvoiceResult.getString("productPlace"));
            vehicleSaleInvoice.setCertificate(queryInvoiceResult.getString("certificate"));
            vehicleSaleInvoice.setCertificateImport(queryInvoiceResult.getString("certificateImport"));
            vehicleSaleInvoice.setInspectionNum(queryInvoiceResult.getString("inspectionNum"));
            vehicleSaleInvoice.setEngineNo(queryInvoiceResult.getString("engineNo"));
            vehicleSaleInvoice.setVehicleNo(queryInvoiceResult.getString("vehicleNo"));
            vehicleSaleInvoice.setTaxBureauCode(queryInvoiceResult.getString("taxBureauCode"));
            vehicleSaleInvoice.setTaxBureauName(queryInvoiceResult.getString("taxBureauName"));
            vehicleSaleInvoice.setTaxRecords(queryInvoiceResult.getString("taxRecords"));
            vehicleSaleInvoice.setTonnage(queryInvoiceResult.getString("tonnage"));
            vehicleSaleInvoice.setLimitPeople(queryInvoiceResult.getString("limitPeople"));
            vehicleSaleInvoice.setTaxRate(queryInvoiceResult.getString("taxRate"));
            return vehicleSaleInvoice;
        } else {
            return null;
        }
    }

}
