package com.dxhy.erp.service.impl;

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

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.ReturnCodeEnum;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.pojo.Authorize;
import com.dxhy.common.util.pojo.GlobalInfo;
import com.dxhy.erp.dao.SysDeptDao;
import com.dxhy.erp.dao.TdxCheckRecordInvoiceDao;
import com.dxhy.erp.entity.SysDeptEntity;
import com.dxhy.erp.entity.TdxCheckInvoiceDetail;
import com.dxhy.erp.entity.TdxCheckRecordInvoice;
import com.dxhy.erp.entity.TdxCheckVehicleSale;
import com.dxhy.erp.model.*;
import com.dxhy.erp.model.auth.InterfaceCode;
import com.dxhy.erp.service.CheckDataService;
import com.dxhy.erp.utils.CheckUtils;

import cn.hutool.core.codec.Base64;
import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaohongyang
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
@Service("checkDataService")
@Slf4j
public class CheckDataServiceImpl extends MpBaseServiceImpl<TdxCheckRecordInvoiceDao, TdxCheckRecordInvoice>
    implements CheckDataService {

    private static final Map<String, Integer> M = new HashMap<>();
    private static final Map<String, Integer> HASH = new HashMap<>();
    @Resource
    private SysDeptDao sysDeptDao;
    @Value("${erp.collectNum}")
    private String collectNum;

    @Override
    public String get(GlobalInfo globalInfo, Map<String, String> map, HttpServletRequest request,
        HttpServletResponse response, Authorize authorize) {
        ReturnStateInfo run = new ReturnStateInfo();
        List<TdxCheckRecordInvoice> list = null;
        List<TdxCheckInvoiceDetail> detailList;
        List<TdxCheckVehicleSale> vehicleList;
        CollectData data = null;
        try {
            data = JSON.parseObject(map.get("data"), CollectData.class);
            run = getCheck(data);
            if (run.getReturnCode() != null || run.getReturnMessage() != null) {
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(run);
                return JSON.toJSONString(interfaceCode);
            }
            if (StringUtils.isNotBlank(data.getQsDateBegin()) || StringUtils.isNotBlank(data.getQsDateEnd())) {
                data.setQsStatus("1");
            }
            if (StringUtils.isNotBlank(data.getTaxPeriod())) {
                data.setRzhStatus("1");
            }
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysDeptEntity deptEntity = sysDeptDao.getOrgByCompany(data.getCompany());
            String dbName = null;
            if (deptEntity != null && deptEntity.getDbName() != null) {
                dbName = deptEntity.getDbName();
            } else {
                ReturnStateInfo runInfo = new ReturnStateInfo();
                runInfo.setReturnCode(ReturnCodeEnum.JTSHBF.getFhzDm());
                runInfo.setReturnMessage(ReturnCodeEnum.JTSHBF.getFhzMc(ReturnCodeEnum.JTSHBF.getIndex()));
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(runInfo);
                return JSON.toJSONString(interfaceCode);
            }
            Integer total = 0;
            try {
                DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
                total = selectByAllCount(data);
            } catch (Exception e) {
                log.info("获取总条数错误：" + e);
                e.printStackTrace();
            }
            // if ("1".equals(data.getStatus())){
            int mxsize = 0;
            int startRow = data.getStartRow();
            String requestRow = data.getRequestRow();

            int endRow = 0;

            if (StringUtils.isNotBlank(requestRow)) {
                if (Integer.parseInt(collectNum) > Integer.parseInt(requestRow)) {

                    endRow = Integer.parseInt(requestRow);
                }
                collectNum = requestRow;

            } else {
                endRow = Integer.parseInt(collectNum);
            }
            // 01回传信息
            List<InvoiceInfo> invoices = new ArrayList<>();
            // 03机动车回传信息
            List<CheckVehicleInfo> vehicleInvoiceInfos = new ArrayList<>();
            boolean continueQuery = true;
            while (continueQuery && mxsize < Integer.parseInt(collectNum) && invoices.size() < total
                && startRow <= total) {
                DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
                list = selectCheckInvoice(data, startRow, endRow);
                log.info("-----------获取查验发票完成----------" + globalInfo.getDataExchangeId());
                startRow += list.size();
                for (TdxCheckRecordInvoice info : list) {
                    String uuid = (StringUtils.isBlank(info.getFpdm())?"":info.getFpdm()) + info.getFphm();
                    if ("03".equals(info.getFpzl())) {
                        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
                        vehicleList = selectVehicle(uuid);
                        if (vehicleList != null && vehicleList.size() > 0) {
                            mxsize += vehicleList.size();
                            for (TdxCheckVehicleSale vehicle : vehicleList) {
                                CheckVehicleInfo vehicleInfo = getVehicleInfo(vehicle, info);
                                vehicleInvoiceInfos.add(vehicleInfo);
                            }
                            if (mxsize > Integer.parseInt(collectNum)) {
                                continueQuery = false;
                                break;
                            }
                        }
                    } else {
                        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
                        detailList = getDetailInfo(uuid);
                        List<InvoiceDetailInfo> listInfo = new ArrayList<>();
                        if (detailList != null && detailList.size() > 0) {
                            mxsize += detailList.size();
                            for (TdxCheckInvoiceDetail detail : detailList) {
                                InvoiceDetailInfo detailInfo = getInvoiceDetailInfo(detail);
                                listInfo.add(detailInfo);
                            }
                        }
                        InvoiceInfo invoiceInfo = getInvoiceInfo(info);
                        invoiceInfo.setDetailList(listInfo);
                        invoices.add(invoiceInfo);
                        if (mxsize >= Integer.parseInt(collectNum)) {
                            continueQuery = false;
                            break;
                        }
                    }
                }
            }
            log.info("===========查验发票实体转换完成============" + globalInfo.getDataExchangeId());
            GatherData gather = new GatherData();
            gather.setStartRow(data.getStartRow());
            gather.setTotalRows(total);
            gather.setContentRows(invoices.size() + vehicleInvoiceInfos.size());
            if (vehicleInvoiceInfos.size() > 0) {
                gather.setCheckVehicleInfo(vehicleInvoiceInfos);
            }
            if (invoices.size() > 0) {
                gather.setInvoices(invoices);
            }
            String result = JSON.toJSONString(gather);
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
            InterfaceCode interfaceCode = new InterfaceCode();
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            interfaceCode.setData(Base64.encode(result));
            return JSON.toJSONString(interfaceCode);
        } catch (Exception e) {
            e.printStackTrace();
            run.setReturnCode("2011");
            run.setReturnMessage("其他异常");
            String globalJson = null;
            String runJson = null;

            runJson = JSON.toJSONString(run);
            globalJson = JSON.toJSONString(globalInfo);

            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            return "{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}";
        }
    }

    public InvoiceInfo getInvoiceInfo(TdxCheckRecordInvoice invoice) {
        InvoiceInfo info = new InvoiceInfo();
        info.setCheckUser(invoice.getCheckUser());
        info.setMachineNo(invoice.getJqbh());
        if(StringUtils.isNotBlank(invoice.getFpdm())){
            info.setInvoiceCode(invoice.getFpdm());
        }else {
            info.setInvoiceCode("");
        }
        info.setInvoiceNo(invoice.getFphm());
        info.setInvoiceDate(invoice.getKprq());
        info.setBuyerAccount(invoice.getGfyhzh());
        info.setBuyerAddressPhone(invoice.getGfdzdh());
        info.setBuyerName(invoice.getGfmc());
        info.setBuyerTaxNo(invoice.getGfsh());
        info.setSalerAccount(invoice.getXfyhzh());
        info.setSalerAddressPhone(invoice.getXfdzdh());
        info.setSalerName(invoice.getXfmc());
        info.setSalerTaxNo(invoice.getXfsh());
        info.setInvoiceAmount(invoice.getJe());
        info.setTaxAmount(invoice.getSe());
        info.setTotalAmount(invoice.getJshj());
        info.setRemark(invoice.getBz());
        if ("Y".equals(invoice.getZfbz())) {

            info.setInvoiceStatus("2");
        } else if ("N".equals(invoice.getZfbz())) {
            info.setInvoiceStatus("0");
        } else {
            info.setInvoiceStatus(invoice.getZfbz());
        }
        info.setInvoiceType(invoice.getFpzl());

        if (StringUtils.isBlank(invoice.getJym())) {
            info.setCheckCode("");
        } else {
            info.setCheckCode(invoice.getJym());
        }
        if (StringUtils.isBlank(invoice.getTxfbz())) {
            info.setTxfbz("");
        } else {
            info.setTxfbz(invoice.getTxfbz());
        }
        if (StringUtils.isBlank(invoice.getLslbz())) {
            info.setLslbz("");
        } else {
            info.setLslbz(invoice.getLslbz());
        }
        return info;
    }

    public InvoiceDetailInfo getInvoiceDetailInfo(TdxCheckInvoiceDetail detail) {
        InvoiceDetailInfo detailInfo = new InvoiceDetailInfo();
        detailInfo.setDetailNo(detail.getDetailNo() + "");
        detailInfo.setGoodsName(detail.getGoodsName());
        if (StringUtils.isBlank(detail.getModel())) {
            detailInfo.setSpecificationModel("");
        } else {
            detailInfo.setSpecificationModel(detail.getModel());
        }
        if (StringUtils.isBlank(detail.getGoodsNum())) {
            detailInfo.setGoodsNum("");
        } else {
            detailInfo.setGoodsNum(detail.getGoodsNum());
        }
        if (detail.getNum() == null || "".equals(detail.getNum())) {
            detailInfo.setNum("0");
        } else {
            detailInfo.setNum(detail.getNum() + "");
        }
        if (StringUtils.isBlank(detail.getUnit())) {
            detailInfo.setUnit("");
        } else {
            detailInfo.setUnit(detail.getUnit());
        }
        if (detail.getUnitPrice() == null) {
            detailInfo.setUnitPrice("");
        } else {
            detailInfo.setUnitPrice(detail.getUnitPrice());
        }
        if (detail.getDetailAmount() == null) {
            detailInfo.setDetailAmount("");
        } else {
            detailInfo.setDetailAmount(detail.getDetailAmount());
        }
        if (detail.getTaxRate() == null) {
            detailInfo.setTaxRate("");
        } else {
            detailInfo.setTaxRate(detail.getTaxRate());
        }
        if (detail.getTaxAmount() == null) {
            detailInfo.setTaxAmount("");
        } else {
            detailInfo.setTaxAmount(detail.getTaxAmount());
        }
        if (StringUtils.isBlank(detail.getCph())) {
            detailInfo.setCph("");
        } else {
            detailInfo.setCph(detail.getCph());
        }
        if (StringUtils.isBlank(detail.getLx())) {
            detailInfo.setLx("");
        } else {
            detailInfo.setLx(detail.getLx());
        }
        if (StringUtils.isBlank(detail.getTxrqq())) {
            detailInfo.setTxrqq("");
        } else {
            detailInfo.setTxrqq(detail.getTxrqq());
        }
        if (StringUtils.isBlank(detail.getTxrqz())) {
            detailInfo.setTxrqz("");
        } else {
            detailInfo.setTxrqz(detail.getTxrqz());
        }
        return detailInfo;
    }

    public List<TdxCheckInvoiceDetail> getDetailInfo(String uuid) {
        return super.baseMapper.selectDetailInfo(uuid);
    }

    public CheckVehicleInfo getVehicleInfo(TdxCheckVehicleSale vehicleSaleInvoice, TdxCheckRecordInvoice veinfo) {
        DecimalFormat df = new DecimalFormat("#0.00");
        CheckVehicleInfo info = new CheckVehicleInfo();
        info.setMachineNo(veinfo.getJqbh());
        if(StringUtils.isNotBlank(veinfo.getFpdm())){
            info.setInvoiceCode(veinfo.getFpdm());
        }else {
            info.setInvoiceCode("");
        }

        info.setInvoiceNo(veinfo.getFphm());
        info.setInvoiceType(veinfo.getFpzl());
        info.setBuyerName(veinfo.getGfmc());
        info.setBuyerTaxNo(veinfo.getGfsh());
        info.setInvoiceDate(veinfo.getKprq());
        info.setCheckUser(veinfo.getCheckUser());
        info.setTaxAmount(df.format(new BigDecimal(veinfo.getSe())));
        info.setTotalAmount(df.format(new BigDecimal(veinfo.getJshj())));
        info.setSalerName(veinfo.getXfmc());
        info.setSalerTaxNo(veinfo.getXfsh());
        info.setSalerAccount(veinfo.getXfyhzh());
        info.setSalerAddressPhone(veinfo.getXfdzdh());
        info.setRemark(veinfo.getBz());
        info.setInvoiceAmount(df.format(new BigDecimal(veinfo.getJe())));
        if (StringUtils.isBlank(veinfo.getGfyhzh())) {
            info.setBuyerAcount("");
        } else {
            info.setBuyerAcount(veinfo.getGfyhzh());
        }
        if (StringUtils.isBlank(veinfo.getGfdzdh())) {
            info.setBuyerAddressPhone("");
        } else {
            info.setBuyerAddressPhone(veinfo.getGfdzdh());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getBuyerIdNum())) {
            info.setBuyerIdNum("");
        } else {
            info.setBuyerIdNum(vehicleSaleInvoice.getBuyerIdNum());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getVehicleType())) {
            info.setVehicleType("");
        } else {
            info.setVehicleType(vehicleSaleInvoice.getVehicleType());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getFactoryModel())) {
            info.setFactoryModel("");
        } else {
            info.setFactoryModel(vehicleSaleInvoice.getFactoryModel());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getProductPlace())) {
            info.setProductPlace("");
        } else {
            info.setProductPlace(vehicleSaleInvoice.getProductPlace());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getCertificate())) {
            info.setCertificate("");
        } else {
            info.setCertificate(vehicleSaleInvoice.getCertificate());
        }

        if (StringUtils.isBlank(vehicleSaleInvoice.getCertificateImport())) {
            info.setCertificateImport("");
        } else {
            info.setCertificateImport(vehicleSaleInvoice.getCertificateImport());
        }

        if (StringUtils.isBlank(vehicleSaleInvoice.getInspectionNum())) {
            info.setInspectionNum("");
        } else {
            info.setInspectionNum(vehicleSaleInvoice.getInspectionNum());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getEngineNo())) {
            info.setEngineNo("");
        } else {
            info.setEngineNo(vehicleSaleInvoice.getEngineNo());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getVehicleNo())) {
            info.setVehicleNo("");
        } else {
            info.setVehicleNo(vehicleSaleInvoice.getVehicleNo());
        }

        if (StringUtils.isBlank(vehicleSaleInvoice.getPhone())) {
            info.setPhone("");
        } else {
            info.setPhone(vehicleSaleInvoice.getPhone());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getBuyerBank())) {
            info.setBuyerBank("");
        } else {
            info.setBuyerBank(vehicleSaleInvoice.getBuyerBank());
        }

        try {
            info.setTaxRate(Double.valueOf(vehicleSaleInvoice.getTaxRate()).intValue() + "");
        } catch (Exception e) {
            info.setTaxRate("0");
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getTaxBureauCode())) {
            info.setTaxBureauCode("");
        } else {
            info.setTaxBureauCode(vehicleSaleInvoice.getTaxBureauCode());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getTaxBureauName())) {
            info.setTaxBureauName("");
        } else {
            info.setTaxBureauName(vehicleSaleInvoice.getTaxBureauName());
        }

        if (StringUtils.isBlank(vehicleSaleInvoice.getTaxRecords())) {
            info.setTaxRecords("");
        } else {
            info.setTaxRecords(vehicleSaleInvoice.getTaxRecords());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getTonnage())) {
            info.setTonnage("");
        } else {
            info.setTonnage(vehicleSaleInvoice.getTonnage());
        }
        if (StringUtils.isBlank(vehicleSaleInvoice.getLimitPeople())) {
            info.setLimitPeople("");
        } else {
            info.setLimitPeople(vehicleSaleInvoice.getLimitPeople());
        }
        if ("Y".equals(veinfo.getZfbz())) {

            info.setInvoiceStatus("2");
        } else if ("N".equals(veinfo.getZfbz())) {
            info.setInvoiceStatus("0");
        } else {
            info.setInvoiceStatus(veinfo.getZfbz());
        }

        return info;
    }

    @Transactional(rollbackFor = Exception.class)
    public Integer selectByAllCount(CollectData data) {
        Map<String, Object> map = new HashMap<>(16);
//        map.put("buyerTaxNo", data.getBuyerTaxNo());
        map.put("company", data.getCompany());
        map.put("invoiceType", data.getInvoiceType());
        map.put("createDateBegin", data.getCreateDateBegin());
        map.put("createDateEnd", data.getCreateDateEnd());
        map.put("startRow", data.getStartRow());
        map.put("requestRow", data.getRequestRow());

        return super.baseMapper.selectAllCount(map);
    }

    @Transactional(rollbackFor = Exception.class)
    public List<TdxCheckRecordInvoice> selectCheckInvoice(CollectData data, Integer start, Integer num) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("company", data.getCompany());
        map.put("invoiceType", data.getInvoiceType());
        map.put("createDateBegin", data.getCreateDateBegin());
        map.put("createDateEnd", data.getCreateDateEnd());
        map.put("startRow", data.getStartRow());
        map.put("requestRow", data.getRequestRow());
        map.put("start", start - 1);
        map.put("num", num);
        return super.baseMapper.selectCheckInvoice(map);
    }

    public ReturnStateInfo getCheck(CollectData data) {
        ReturnStateInfo run = new ReturnStateInfo();

        if (CheckUtils.isNullOrEmpty(data.getCompany())) {
            run.setReturnCode(ReturnCodeEnum.QYBS.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.QYBS.getFhzMc(ReturnCodeEnum.QYBS.getIndex()));
        }

        if (CheckUtils.isNullOrEmpty(data.getCreateDateBegin())
            || (!CheckUtils.stringLength(data.getCreateDateBegin(), 14))) {
            run.setReturnCode(ReturnCodeEnum.QSRQBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.QSRQBNWK.getFhzMc(ReturnCodeEnum.QSRQBNWK.getIndex()));
        }
        if (CheckUtils.isNullOrEmpty(data.getCreateDateEnd())
            || (!CheckUtils.stringLength(data.getCreateDateEnd(), 14))) {
            run.setReturnCode(ReturnCodeEnum.JSRQBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.JSRQBNWK.getFhzMc(ReturnCodeEnum.JSRQBNWK.getIndex()));
        }
        if (CheckUtils.isNullOrEmpty(data.getStatus()) || (!CheckUtils.stringLength(data.getStatus(), 1))) {
            run.setReturnCode(ReturnCodeEnum.ZTBZBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.ZTBZBNWK.getFhzMc(ReturnCodeEnum.ZTBZBNWK.getIndex()));
        }
        if (!CheckUtils.checkNum(data.getStartRow())) {
            run.setReturnCode(ReturnCodeEnum.KSHSCW.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.KSHSCW.getFhzMc(ReturnCodeEnum.KSHSCW.getIndex()));
        }
        return run;
    }

    public List<TdxCheckVehicleSale> selectVehicle(String uuid) {
        return super.baseMapper.selectVehicle(uuid);
    }
}
