package com.dxhy.erp.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.dxhy.common.utils.DateUtils;
import com.dxhy.erp.entity.*;
import com.dxhy.erp.utils.CheckUtil;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

/**
 * 调用查验接口业务层
 *
 * @author JLY
 * @date 2017年6月26日下午5:02:49
 */
@SuppressWarnings("AlibabaUndefineMagicConstant")
@Service
@Slf4j
public class CheckService {
    /**
     * 单张查验发票
     *
     * @author JLY
     * @throws Exception
     *             异常
     * @date 2017年6月26日下午6:32:15
     */

    public FP getCheck(CheckInvoiceParam param) throws Exception {
        log.info("查询信息为=====" + param);
        CheckInvoiceParam entity = new CheckInvoiceParam();
        entity.setInvoiceCode(param.getInvoiceCode());
        entity.setInvoiceNo(param.getInvoiceNo());
        String invoiceDate = param.getInvoiceDate();
        if (invoiceDate.length() > 8) {
            String year = invoiceDate.substring(0, 4);
            String month = invoiceDate.substring(5, 7);
            String day = invoiceDate.substring(8, 10);
            invoiceDate = year + month + day;
        }
        entity.setInvoiceDate(invoiceDate);
        entity.setInvoiceType(param.getInvoiceType());
        entity.setInvoiceAmount(param.getInvoiceAmount());
        entity.setCheckCode(param.getCheckCode());
        log.info("请求的数据为" + entity);
        FP check = CheckUtil.getCheck(entity);
        log.info("响应的数据为" + check);
        return check;
    }

    /**
     * 批量查验发票
     *
     * @author JLY
     * @date 2017年6月30日上午11:42:55
     */
    public synchronized List<FP> getCheck(final List<CheckInvoiceParam> checkParams) throws Exception {
        final List<FP> fpList = new ArrayList<>();

        ExecutorService threadPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
            new SynchronousQueue<>(), ThreadFactoryBuilder.create().setDaemon(true).build());
        for (final CheckInvoiceParam cp : checkParams) {
            // final int task = i; //线程任务
            TimeUnit.MILLISECONDS.sleep(100);
            // 接受一个Runnable实例
            threadPool.execute(new Runnable() {
                final CheckService checkService = new CheckService();

                @Override
                public void run() {
                    try {
                        FP resEntity = checkService.getCheck(cp);
                        fpList.add(resEntity);
                    } catch (Exception e) {
                       log.info("业务处理异常：{}", e);
                    }
                }
            });

        }
        threadPool.shutdown();
        while (true) {
            // 线程执行完毕后返回查验结果
            if (threadPool.isTerminated()) {
                return fpList;
            }
            Thread.sleep(200);
        }
    }

    /**
     * 查验转实体
     *
     * @author JLY
     * @date 2017年7月3日下午8:32:39
     */
    public List<RecordInvoice> toToRecordInvoices(List<FP> fpList) throws Exception {
        List<RecordInvoice> res = new ArrayList<>();
        RecordInvoice po;
        for (FP o : fpList) {
            if (o != null && "0001".equals(o.getCYJG_CODE())) {
                po = new RecordInvoice();
                po.setInvoiceType(o.getFPZL());
                po.setInvoiceCode(o.getFPDM());
                po.setInvoiceNo(o.getFPHM());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                try {
                    po.setInvoiceDate(sdf.parse(o.getKPRQ()));
                } catch (Exception e) {
                    po.setInvoiceDate(null);
                }
                po.setGfTaxNo(o.getGFSH());
                po.setGfName(o.getGFMC());
                po.setGfAddressAndPhone(o.getGFDZDH());
                po.setGfBankAndNo(o.getGFYHZH());
                po.setXfTaxNo(o.getXFSH());
                po.setXfName(o.getXFMC());
                po.setXfAddressAndPhone(o.getXFDZDH());
                po.setXfBankAndNo(o.getXFYHZH());
                if ("N".equals(o.getZFBZ())) {
                    po.setInvoiceStatus("0");
                } else if ("Y".equals(o.getZFBZ())) {
                    po.setInvoiceStatus("2");
                } else {
                    po.setInvoiceStatus(o.getZFBZ());
                }
                if (!"".equals(o.getJE()) && o.getJE() != null && !(" ").equals(o.getJE())) {
                    try {
                        po.setInvoiceAmount(new BigDecimal(o.getJE()));
                    } catch (Exception e) {
                        po.setInvoiceAmount(new BigDecimal("0.00"));
                    }
                }
                if (!"".equals(o.getSE()) && o.getSE() != null && !(" ").equals(o.getSE())) {
                    try {
                        po.setTaxAmount(new BigDecimal(o.getSE()));
                    } catch (Exception e) {
                        po.setTaxAmount(new BigDecimal("0.00"));
                    }
                }
                if (!"".equals(o.getJSHJ()) && o.getJSHJ() != null && !(" ").equals(o.getJSHJ())) {
                    try {
                        po.setTotalAmount(new BigDecimal(o.getJSHJ()));
                    } catch (Exception e) {
                        po.setTotalAmount(new BigDecimal("0.00"));
                    }
                }
                po.setUuid(o.getFPDM() + o.getFPHM());
                po.setRemark(o.getBZ());
                po.setCheckCode(o.getJYM());
                po.setDetailYesorno(1);
                po.setDetailList(this.toDetailList(o.getXM()));
                res.add(po);
            } else {
                po = new RecordInvoice();
                po.setNode(o.getCYJG_TIP());
                po.setInvoiceCode(o.getFPDM());
                po.setInvoiceNo(o.getFPHM());
                res.add(po);
            }
        }
        return res;
    }

    /**
     * 查验转实体
     *
     * @author wy
     * @date 2018年7月13日上午11:29:01
     */
    public RecordInvoice toToRecordInvoices(FP o) throws Exception {

        RecordInvoice po;

        if (o != null && "0001".equals(o.getCYJG_CODE())) {
            po = new RecordInvoice();
            po.setInvoiceType(o.getFPZL());
            po.setInvoiceCode(o.getFPDM());
            po.setInvoiceNo(o.getFPHM());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            try {
                po.setInvoiceDate(sdf.parse(o.getKPRQ()));
            } catch (Exception e) {
                po.setInvoiceDate(null);
            }
            po.setGfTaxNo(o.getGFSH());
            po.setGfName(o.getGFMC());
            po.setGfAddressAndPhone(o.getGFDZDH());
            po.setGfBankAndNo(o.getGFYHZH());
            po.setXfTaxNo(o.getXFSH());
            po.setXfName(o.getXFMC());
            po.setXfAddressAndPhone(o.getXFDZDH());
            po.setXfBankAndNo(o.getXFYHZH());
            if ("N".equals(o.getZFBZ())) {
                po.setInvoiceStatus("0");
            } else if ("Y".equals(o.getZFBZ())) {
                po.setInvoiceStatus("2");
            } else {
                po.setInvoiceStatus(o.getZFBZ());
            }
            if (!"".equals(o.getJE()) && o.getJE() != null && !(" ").equals(o.getJE())) {
                try {
                    po.setInvoiceAmount(new BigDecimal(o.getJE()));
                } catch (Exception e) {
                    po.setInvoiceAmount(new BigDecimal("0.00"));
                }
            }
            if (!"".equals(o.getSE()) && o.getSE() != null && !(" ").equals(o.getSE())) {
                try {
                    po.setTaxAmount(new BigDecimal(o.getSE()));
                } catch (Exception e) {
                    po.setTaxAmount(new BigDecimal("0.00"));
                }
            }
            if (!"".equals(o.getJSHJ()) && o.getJSHJ() != null && !(" ").equals(o.getJSHJ())) {
                try {
                    po.setTotalAmount(new BigDecimal(o.getJSHJ()));
                } catch (Exception e) {
                    po.setTotalAmount(new BigDecimal("0.00"));
                }
            }
            po.setUuid(o.getFPDM() + o.getFPHM());
            po.setRemark(o.getBZ());
            po.setCheckCode(o.getJYM());
            po.setDetailYesorno(1);
            po.setDetailList(this.toDetailList(o.getXM()));

        } else {
            po = new RecordInvoice();
            assert o != null;
            po.setNode(o.getCYJG_TIP());
            po.setInvoiceCode(o.getFPDM());
            po.setInvoiceNo(o.getFPHM());

        }

        return po;
    }

    private ArrayList<RecordInvoiceDetail> toDetailList(List<MX> mx) {
        ArrayList<RecordInvoiceDetail> detailList = new ArrayList<>();
        RecordInvoiceDetail rd;
        int i = 0;
        for (MX xx : mx) {
            rd = new RecordInvoiceDetail();
            if (StringUtils.isNotBlank(xx.getMXXH())) {
                rd.setDetailNo(Integer.parseInt(xx.getMXXH()));
            } else {
                rd.setDetailNo(i + 1);
            }
            rd.setGoodName(xx.getMC());
            rd.setModel(xx.getGGXH());
            rd.setUnit(xx.getJLDW());
            if (!"".equals(xx.getSHUL()) && xx.getSHUL() != null && !(" ").equals(xx.getSHUL())) {
                rd.setNum(xx.getSHUL());
            }
            if (!"".equals(xx.getDJ()) && xx.getDJ() != null && !(" ").equals(xx.getDJ())) {
                rd.setUnitPrice(xx.getDJ());
            }
            rd.setDetailAmount(xx.getJE());

            rd.setTaxRate(xx.getSL());

            rd.setTaxAmount(xx.getSE());

            detailList.add(rd);
        }
        return detailList;
    }

    /**
     * 设置查验参数
     *
     * @author JLY
     * @date 2017年6月30日上午10:49:26
     */
    public List<CheckInvoiceParam> adapterToCheckInvoiceParam(List<SignedInvoiceVo> signedInvoiceVos) {
        List<CheckInvoiceParam> cps = new ArrayList<>();
        CheckInvoiceParam pm;
        for (SignedInvoiceVo vo : signedInvoiceVos) {
            if (null == vo.getNotes()) {
                pm = new CheckInvoiceParam();
                pm.setInvoiceCode(vo.getInvoiceCode());
                pm.setInvoiceNo(vo.getInvoiceNo());

                try {
                    pm.setInvoiceDate(vo.getInvoiceDate().replaceAll("-", ""));
                } catch (Exception e) {
                    pm.setInvoiceDate(DateUtils.dateToStr(DateUtils.getSqlDate()));
                    log.error("转换发票查验参数开票日期错误", e);
                }
                pm.setInvoiceType(vo.getInvoiceType());
                pm.setInvoiceAmount("1".equals(vo.getInvoiceType()) ? vo.getInvoiceAmount() : null);
                pm.setCheckCode("1".equals(vo.getInvoiceType()) ? null : vo.getCheckCode());
                cps.add(pm);
            }
        }
        return cps;
    }

}
