package com.dxhy.base.service.fpcj;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.dxhy.common.constant.DictConstant;
import com.dxhy.common.service.DictdetaServcice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.base.dao.BaseTDxRecordInvoiceDao;
import com.dxhy.base.entity.BaseTDxRecordInvoice;
import com.dxhy.base.entity.BaseTDxRecordInvoiceDetail;
import com.dxhy.base.entity.BaseTDxVehicleSaleInvoice;
import com.dxhy.base.model.BaseFpcjCjhzRespVO;
import com.dxhy.base.model.BaseFpcjCjmxRespVO;
import com.dxhy.base.model.BaseFpcjWbfpmxRespVO;
import com.dxhy.base.service.singletable.BaseIInvoiceDetail;
import com.dxhy.base.service.singletable.BaseIJdcService;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.utils.DateUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 *
 *
 * 发票采集明细查询实现
 *
 * @author peipei.li
 * @date 2019-04-23
 *
 */
@SuppressWarnings({"AlibabaLowerCamelCaseVariableNaming", "AlibabaUndefineMagicConstant"})
@Service("baseIFpcjmxService")
public class BaseFpcjmxServiceImpl extends MpBaseServiceImpl<BaseTDxRecordInvoiceDao, BaseTDxRecordInvoice>
    implements BaseIFpcjmxService {

    @Resource
    private BaseIJdcService baseIJdcService;

    @Resource
    private BaseIInvoiceDetail baseIInvoiceDetail;
    @Resource
    private TabulateRedisService tabulateRedisService;
    @Resource
    private DictdetaServcice dictdetaServcice;

    @Override
    public String selectCjmxByGfshAndCjrq(Map<String, Object> pramsMap, int curr, int size) {

        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);

        String[] titlelist = {"序号", "发票代码", "发票号码","全电发票号码", "开票日期", "购方名称", "销方名称", "金额", "税额"};
        String[] titleprop = {"xh", "fpdm", "fphm","qdfphm", "kprq", "gfmc", "xfmc", "je", "se"};

        boolean getYcp = false;
        if (pramsMap.containsKey("ycpbz")) {
            getYcp = true;
        }

        if (getYcp) {
            titlelist = new String[] {"序号", "发票代码", "发票号码","全电发票号码", "开票日期", "购方名称", "销方名称", "金额", "税额", "异常状态", "异常日期"};
            titleprop = new String[] {"xh", "fpdm", "fphm", "qdfphm","kprq", "gfmc", "xfmc", "je", "se", "yczt", "ycrq"};
        }

        // 需要设置返回列表标题时调用
        JSONObject json = super.setTitleList(titlelist, titleprop);

        PageHelper.startPage(curr, size);
        List<BaseTDxRecordInvoice> pageList = super.baseMapper.selectCjmxByGfshAndCjrq(pramsMap);
        PageInfo<BaseTDxRecordInvoice> pageInfo = new PageInfo<>(pageList);
        List<BaseTDxRecordInvoice> resultList = pageInfo.getList();

        // 设置记录总数
        json.put("total", pageInfo.getTotal());

        List<Object> returnList = new ArrayList<>();
        if (resultList != null && resultList.size() > 0) {
            int start = new Long(pageInfo.getStartRow()).intValue();

            for (int i = 0; i < resultList.size(); i++) {
                BaseFpcjCjmxRespVO mxlb = this.convertToMxlbView(resultList.get(i), start + i, getYcp);
                returnList.add(mxlb);
            }
        }
        json.put("datalist", returnList);

        return super.responseResult(json);
    }

    /**
     * 把查询结果转换为汇总明细列表格式
     *
     * @param tDxRecordInvoice
     *            抵账信息
     * @param i
     *            序号
     * @param getYcp
     *            异常状态
     * @return 返回
     *
     */
    private BaseFpcjCjmxRespVO convertToMxlbView(BaseTDxRecordInvoice tDxRecordInvoice, int i, boolean getYcp) {
        BaseFpcjCjmxRespVO cjmx = new BaseFpcjCjmxRespVO();
        cjmx.setXh(String.valueOf(i));
        cjmx.setFpdm(tDxRecordInvoice.getInvoiceCode());
        cjmx.setFphm(tDxRecordInvoice.getInvoiceNo());
        cjmx.setGfmc((tDxRecordInvoice.getGfName() == null) ? "" : tDxRecordInvoice.getGfName());
        cjmx.setQdfphm((tDxRecordInvoice.getEleInvoiceNo() == null) ? "" : tDxRecordInvoice.getEleInvoiceNo());
        cjmx.setJe(AmountFormatUtil.fmtMicrometer(MathUtil.round(tDxRecordInvoice.getInvoiceAmount().toPlainString())));
        cjmx.setKprq(DateUtils.dateToStr(tDxRecordInvoice.getInvoiceDate()));
        cjmx.setSe(AmountFormatUtil.fmtMicrometer(MathUtil.round(tDxRecordInvoice.getTaxAmount().toPlainString())));
        cjmx.setXfmc((tDxRecordInvoice.getXfName() == null) ? "" : tDxRecordInvoice.getXfName());
        cjmx.setInvoiceType(tDxRecordInvoice.getInvoiceType());
        if (getYcp) {
            String fpzt = tDxRecordInvoice.getInvoiceStatus();
            cjmx.setYczt(dictdetaServcice.queryDictName(DictConstant.INVOICE_STATUS,fpzt));
            cjmx.setYcrq((tDxRecordInvoice.getStatusUpdateDate() == null) ? ""
                : DateUtils.dateToStr(tDxRecordInvoice.getStatusUpdateDate()));
        }
        return cjmx;
    }

    @Override
    public String selectWbfpmx(Map<String, Object> pramsMap, int curr, int size) {
        List<BaseTDxRecordInvoice> resultList = new ArrayList<>();
        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
        String company = (String)pramsMap.get("company");
        String menuId = (String)pramsMap.get("menuId");
        JSONObject json = tabulateRedisService.getTabulateMenu(company, menuId);

        List<String> gfshList = (List<String>)pramsMap.get("gfsh");

        if (gfshList.size() == 0) {
            // 未从getUserInfo()获取到购方税号信息
            json.put("hjsl", "0");
            json.put("hjje", "0");
            json.put("hjse", "0");
            json.put("total", "0");
            json.put("datalist", new ArrayList<BaseFpcjCjhzRespVO>());
        } else {
            // 合计信息,仅第一页时需要统计，减少数据库压力
            if (curr == 1) {
                long hjsl;
                String hjje = "0";
                String hjse = "0";
                List<BaseTDxRecordInvoice> hjList = super.baseMapper.selectWbfpmxHj(pramsMap);
                BaseTDxRecordInvoice hjxx = hjList.get(0);
                hjsl = hjxx.getId();
                if (hjsl > 0) {
                    hjje = AmountFormatUtil.fmtMicrometer(MathUtil.round(hjxx.getInvoiceAmount().toPlainString()));
                    hjse = AmountFormatUtil.fmtMicrometer(MathUtil.round(hjxx.getTaxAmount().toPlainString()));
                }
                json.put("hjsl", hjsl);
                json.put("hjje", hjje);
                json.put("hjse", hjse);
                if (0 == hjsl) {
                    json.put("total", 0);
                    json.put("datalist", resultList);
                    return super.responseResult(json);
                }
            }

            // 分页获取明细列表
            PageHelper.startPage(curr, size);
            List<BaseTDxRecordInvoice> pageList = super.baseMapper.selectWbfpmx(pramsMap);
            PageInfo<BaseTDxRecordInvoice> pageInfo = new PageInfo<>(pageList);
            resultList = pageInfo.getList();

            // 设置记录总数
            json.put("total", pageInfo.getTotal());

            List<Object> returnList = new ArrayList<>();
            if (resultList != null && resultList.size() > 0) {
                int start = new Long(pageInfo.getStartRow()).intValue();

                for (int i = 0; i < resultList.size(); i++) {
                    BaseFpcjWbfpmxRespVO mxlb = this.convertToWbmxView(resultList.get(i), start + i);
                    returnList.add(mxlb);
                }
            }
            json.put("datalist", returnList);
        }
        return super.responseResult(json);
    }

    /**
     * 转换查询结果为未补明细响应对象
     *
     * @param tDxRecordInvoice
     *            待转换的对象
     * @param i
     *            序号
     * @return 返回
     *
     */
    private BaseFpcjWbfpmxRespVO convertToWbmxView(BaseTDxRecordInvoice tDxRecordInvoice, int i) {
        BaseFpcjWbfpmxRespVO wbmx = new BaseFpcjWbfpmxRespVO();
        wbmx.setId(String.valueOf(i));
        wbmx.setXh(String.valueOf(i));
        wbmx.setFpdm(tDxRecordInvoice.getInvoiceCode());
        wbmx.setFphm(tDxRecordInvoice.getInvoiceNo());
        wbmx.setKprq(DateUtils.dateToStr(tDxRecordInvoice.getInvoiceDate()));
        wbmx.setJe(AmountFormatUtil.fmtMicrometer(MathUtil.round(tDxRecordInvoice.getInvoiceAmount().toPlainString())));
        wbmx.setSe(AmountFormatUtil.fmtMicrometer(MathUtil.round(tDxRecordInvoice.getTaxAmount().toPlainString())));
        wbmx.setGfmc((tDxRecordInvoice.getGfName() == null) ? "" : tDxRecordInvoice.getGfName());
        wbmx.setXfmc((tDxRecordInvoice.getXfName() == null) ? "" : tDxRecordInvoice.getXfName());
        wbmx.setJym((tDxRecordInvoice.getCheckCode() == null) ? "" : tDxRecordInvoice.getCheckCode());
        wbmx.setEleInvoiceNo((tDxRecordInvoice.getEleInvoiceNo() == null) ? "" : tDxRecordInvoice.getEleInvoiceNo());
        wbmx.setCjrq(DateUtils.dateToStr(tDxRecordInvoice.getCreateDate()));
        wbmx.setFplx(tDxRecordInvoice.getInvoiceType());
        wbmx.setInvoiceType(tDxRecordInvoice.getInvoiceType());
        wbmx.setInvoiceSource(dictdetaServcice.queryDictName(DictConstant.INVOICE_SOURCE,tDxRecordInvoice.getInvoiceSource()));
        wbmx.setTotalAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(tDxRecordInvoice.getTotalAmount().toPlainString())));
        return wbmx;
    }

    @Override
    public void insertInvoiceDetail(JSONObject invoiceDetails, String dbName) {
        String invoiceType = invoiceDetails.getString("invoiceType");
        JSONArray detailArray = (JSONArray)invoiceDetails.get("invoiceDetail");

        String uuid = "";

        // 专票和通行费发票货物可以是多条
        if (FplxEnum.ZP.getFplxDm().equals(invoiceType) || FplxEnum.DZZP.getFplxDm().equals(invoiceType)
            || FplxEnum.TXF.getFplxDm().equals(invoiceType)) {
            DynamicContextHolder.push(dbName + DbConstant.DETAIL_WRITE);
            List<BaseTDxRecordInvoiceDetail> invoiceDetailList = new ArrayList<>(detailArray.size());
            for (int i = 0; i < detailArray.size(); i++) {
                JSONObject invoiceDetailJson = detailArray.getJSONObject(i);
                BaseTDxRecordInvoiceDetail invoiceDetail = this.convertToInvoiceDetail(invoiceDetailJson);
                invoiceDetailList.add(invoiceDetail);
                // 每条明细的发票代码、发票号码相同，只取第一条即可
                if (i == 0) {
                    String invoiceCode = invoiceDetail.getInvoiceCode();
                    String invoiceNo = invoiceDetail.getInvoiceNo();
                    uuid = invoiceCode + invoiceNo;
                }
            }
            this.saveInvoiceDetail(invoiceDetailList);
        } else if (FplxEnum.JDC.getFplxDm().equals(invoiceType)) {
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
            JSONObject jdcInvoiceDetailJson = detailArray.getJSONObject(0);

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

            // 机动车仅有一条明细
            BaseTDxVehicleSaleInvoice jdcInvoiceDetail = this.convertToJdcmx(jdcInvoiceDetailJson);
            this.saveJdcDetail(jdcInvoiceDetail);
        }

        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
        // 根据uuid更新明细是否存在标志
        super.baseMapper.updateDetailYesornoByUuid(uuid);
    }

    /**
     * 保存发票底账明细
     *
     * @param invoiceDetailList
     *            明细信息
     *
     */
    @Transactional(rollbackFor = Exception.class)
    void saveInvoiceDetail(List<BaseTDxRecordInvoiceDetail> invoiceDetailList) {

        // 批量保存批量操作的大小

        int batchSize = 500;
        baseIInvoiceDetail.saveBatch(invoiceDetailList, batchSize);
    }

    /**
     *
     * 保存机动车明细
     *
     * @param jdcInvoiceDetail
     *            机动车明细
     *
     */
    @Transactional(rollbackFor = Exception.class)
    void saveJdcDetail(BaseTDxVehicleSaleInvoice jdcInvoiceDetail) {
        baseIJdcService.save(jdcInvoiceDetail);
    }

    /**
     * 转换为发票明细对象
     *
     * @param invoiceDetailJson
     *            发票明细
     * @return 返回
     *
     */
    private BaseTDxRecordInvoiceDetail convertToInvoiceDetail(JSONObject invoiceDetailJson) {

        BaseTDxRecordInvoiceDetail invoiceDetail = new BaseTDxRecordInvoiceDetail();

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

        invoiceDetail.setUuid(uuid);
        invoiceDetail.setCph(invoiceDetailJson.getString("cph"));
        invoiceDetail.setDetailAmount(invoiceDetailJson.getString("detailAmount"));
        invoiceDetail.setDetailNo(invoiceDetailJson.getString("detailNo"));
        invoiceDetail.setGoodsName(invoiceDetailJson.getString("goodsName"));
        invoiceDetail.setGoodsNum(invoiceDetailJson.getString("goodsNum"));
        invoiceDetail.setInvoiceCode(invoiceCode);
        invoiceDetail.setInvoiceNo(invoiceNo);
        invoiceDetail.setLx(invoiceDetailJson.getString("lx"));
        invoiceDetail.setModel(invoiceDetailJson.getString("txrqq"));
        invoiceDetail.setNum(invoiceDetailJson.getString("num"));
        invoiceDetail.setTaxAmount(invoiceDetailJson.getString("taxAmount"));
        invoiceDetail.setTaxRate(invoiceDetailJson.getString("taxRate"));
        invoiceDetail.setTxrqq(invoiceDetailJson.getString("txrqq"));
        invoiceDetail.setTxrqz(invoiceDetailJson.getString("txrqz"));
        invoiceDetail.setUnit(invoiceDetailJson.getString("unit"));
        invoiceDetail.setUnitPrice(invoiceDetailJson.getString("unitPrice"));

        return invoiceDetail;
    }

    /**
     * 转换为机动车明细对象
     *
     * @param jdcInvoiceDetailJson
     *            机动车明细
     * @return 返回
     *
     */
    private BaseTDxVehicleSaleInvoice convertToJdcmx(JSONObject jdcInvoiceDetailJson) {
        String invoiceCode = jdcInvoiceDetailJson.getString("invoiceCode");
        String invoiceNo = jdcInvoiceDetailJson.getString("invoiceNo");
        String uuid = invoiceCode + invoiceNo;

        BaseTDxVehicleSaleInvoice jdcmx = new BaseTDxVehicleSaleInvoice();
        jdcmx.setUuid(uuid);
        jdcmx.setBuyerBank(jdcInvoiceDetailJson.getString("buyerBank"));
        jdcmx.setBuyerIdNum(jdcInvoiceDetailJson.getString("buyerIdNum"));
        jdcmx.setCertificate(jdcInvoiceDetailJson.getString("certificate"));
        jdcmx.setCertificateImport(jdcInvoiceDetailJson.getString("certificateImport"));
        jdcmx.setCheckStatus(jdcInvoiceDetailJson.getString("checkStatus"));
        jdcmx.setCreateDate(DateUtils.getSqlDateLong());
        jdcmx.setEngineNo(jdcInvoiceDetailJson.getString("engineNo"));
        jdcmx.setFactoryModel(jdcInvoiceDetailJson.getString("factoryModel"));
        jdcmx.setInspectionNum(jdcInvoiceDetailJson.getString("inspectionNum"));
        jdcmx.setLimitPeople(jdcInvoiceDetailJson.getString("limitPeople"));
        jdcmx.setPhone(jdcInvoiceDetailJson.getString("phone"));
        jdcmx.setProductPlace(jdcInvoiceDetailJson.getString("productPlace"));
        jdcmx.setTaxBureauCode(jdcInvoiceDetailJson.getString("taxBureauCode"));
        jdcmx.setTaxBureauName(jdcInvoiceDetailJson.getString("taxBureauName"));
        jdcmx.setTaxRate(jdcInvoiceDetailJson.getString("taxRate"));
        jdcmx.setTaxRecords(jdcInvoiceDetailJson.getString("taxRecords"));
        jdcmx.setTonnage(jdcInvoiceDetailJson.getString("tonnage"));
        jdcmx.setVehicleNo(jdcInvoiceDetailJson.getString("vehicleNo"));
        jdcmx.setVehicleType(jdcInvoiceDetailJson.getString("vehicleType"));
        return jdcmx;
    }

}
