package com.jkcredit.invoice.service.nocar.impl;

import cn.com.taiji.sdk.model.comm.protocol.tts.vehicle.VehicleQueryResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jkcredit.invoice.mapper.customer.CustomerCarRecMapper;
import com.jkcredit.invoice.mapper.waybill.NoCarWaybillMapper;
import com.jkcredit.invoice.model.entity.customer.CustomerCarRec;
import com.jkcredit.invoice.model.entity.customer.CustomerRec;
import com.jkcredit.invoice.model.entity.waybill.NoCarWayBill;
import com.jkcredit.invoice.service.customer.CustomerOperService;
import com.jkcredit.invoice.service.customer.CustomerRecService;
import com.jkcredit.invoice.service.customer.CustomerService;
import com.jkcredit.invoice.service.lowerservice.NoCarService;
import com.jkcredit.invoice.service.nocar.NoCarBillWayImportService;
import com.jkcredit.invoice.service.nocar.NoCarBillWayService;
import com.jkcredit.invoice.service.thead.ThreadPoolFactory;
import com.jkcredit.invoice.util.DateUtil;
import com.jkcredit.invoice.util.RespR;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;

import static com.jkcredit.invoice.common.CommonConst.INTONE;
import static com.jkcredit.invoice.common.CommonConst.INTTHREE;
import static com.jkcredit.invoice.common.CommonConst.INTTOW;

/**
 * 运单维护接口实现类
 * @author mumuxigua
 */
@Service
@Slf4j
public class NoCarBillWayServiceImpl extends ServiceImpl<NoCarWaybillMapper, NoCarWayBill> implements NoCarBillWayService {

    public static ExecutorService executorService = ThreadPoolFactory.getThreadPool("batchBillWayStart", 5, 10);

    @Autowired
    NoCarWaybillMapper noCarWaybillMapper;

    @Autowired
    CustomerCarRecMapper customerCarRecMapper;

    @Autowired
    NoCarService noCarService;

    @Autowired
    CustomerRecService customerRecMapper;

    @Autowired
    CustomerOperService customerOperService;

    @Autowired
    CustomerService customerService;

    @Autowired
    NoCarBillWayImportService noCarWaybillMapperImprt;

    @Override
    public IPage<List<NoCarWayBill>> findByPageAndWayBill(Page page, NoCarWayBill noCarWayBill) {
        return noCarWaybillMapper.selectAllByPage(page, noCarWayBill);
    }
    @Override
    public IPage<List<NoCarWayBill>> findByPageAndWayBillHis(Page page, NoCarWayBill noCarWayBill) {
        return noCarWaybillMapper.selectAllByPageHis(page, noCarWayBill);
    }
    @Override
    public IPage<List<NoCarWayBill>> findByPageAndWayBillException(Page page, NoCarWayBill noCarWayBill) {
        return noCarWaybillMapper.selectAllByPageException(page, noCarWayBill);
    }

    /**
     * 插入或者更新运单
     * @param noCarWayBill
     */
    public void insertOrUpdateBillStart(NoCarWayBill noCarWayBill) {
        noCarWayBill.setIntfaceStartTime(DateUtil.getCurrentDateStr());
        noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
        NoCarWayBill curr = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        if (curr == null) {
            noCarWaybillMapper.insert(noCarWayBill);
        } else {
            if (curr.getBillwayStatus() < 1) {
                noCarWaybillMapper.updateByBillNum(noCarWayBill);
            }
        }
    }

    @Override
    public RespR batchBillWayStart(List<NoCarWayBill> noCarWayBills, String customerName,String fileBatchNum) {
        log.info("开始平台指令上传NoCarBillWayServiceImpl.batchBillWayStart,上传数量" + noCarWayBills.size());
        if (!customerService.checkMoneyEnough(customerName)) {
            return new RespR(false, "余额不足");
        }
        StringBuffer stringBuffer = new StringBuffer();
        //保存批次号信息
        String batchNumber = customerOperService.saveCustomerOper(customerName, 1);
        executorService.execute(() -> {
            noCarWayBills.parallelStream().forEach(noCarWayBill -> {
                //根据税号，查询备案企业
                CustomerRec customerRec = new CustomerRec();
                customerRec.setCustomerName(customerName);
                customerRec.setCompanyReferencenum(noCarWayBill.getTaxplayerCode());
                noCarWayBill.setBatchNum(batchNumber);
                noCarWayBill.setCustomerName(customerName);
                noCarWayBill.setBillwayStatus(-2);
                noCarWayBill.setHisFlag(0);
                noCarWayBill.setIntfaceStartTime(DateUtil.getCurrentDateStr());
                noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
                noCarWaybillMapperImprt.insertImport(noCarWayBill);
                customerRec = customerRecMapper.selectByCustomerNameAndCompanyReference(customerRec);
                if (customerRec == null) {
                    noCarWaybillMapperImprt.updateBillway(-2, "企业税号未备案", noCarWayBill);
                    noCarWayBill.setFailReason("企业税号未备案");
                    noCarWayBill.setBillwayStatus(-2);
                    insertOrUpdateBillStart(noCarWayBill);
                    stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append("企业税号未备案#");
                    return;
                }
                noCarWayBill.setCompanyName(customerRec.getCompanyName());
                noCarWayBill.setCompanyNum(customerRec.getCompanyNum());
                if (DateUtil.getDistanceHours(noCarWayBill.getStartTime(), new Date()) < INTONE) {
                    noCarWaybillMapperImprt.updateBillway(-2, "失败，运单开始时间超72小时#", noCarWayBill);
                    noCarWayBill.setBillwayStatus(-2);
                    noCarWayBill.setFailReason("失败，运单开始时间超72小时");
                    insertOrUpdateBillStart(noCarWayBill);
                    return;

                }
                //1.查询是否有车辆备案
                CustomerCarRec customerCarRec;

                //2.无车车辆备案时进行车辆备案

                List<CustomerCarRec> customerCarRecs = new ArrayList<>();
                customerCarRec = new CustomerCarRec();
                customerCarRec.setCompanyName(noCarWayBill.getCompanyName());
                customerCarRec.setCarNum(noCarWayBill.getPlateNum());
                customerCarRec.setCarColor(noCarWayBill.getPlateColor());
                customerCarRec.setCustomerName(customerName);
                customerCarRec.setInterType(1);
                customerCarRec.setCompanyNum(customerRec.getCompanyNum());
                customerCarRec.setBusinessType("2");
                customerCarRec.setServiceOperation(1);//默认运营车辆
                noCarWayBill.setTitleType(2);
                //先查询上游是否已经备案
                RespR<VehicleQueryResponse> respRquery = noCarService.customerCarRecQueryUpper(customerCarRec);
                if (respRquery.getCode() == 1 || respRquery.getData() == null || respRquery.getData().getResult() == null || respRquery.getData().getResult().size() <= 0) {
                    customerCarRecs.add(customerCarRec);
                    RespR respR = noCarService.customerCarRec(customerCarRecs);
                    if (respR.getCode() == 1) {
                        stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append(respR.getMsg()).append("#");
                        noCarWaybillMapperImprt.updateBillway(-2, respR.getMsg(), noCarWayBill);
                        noCarWayBill.setBillwayStatus(-2);
                        noCarWayBill.setFailReason(respR.getMsg());
                        insertOrUpdateBillStart(noCarWayBill);
                        return;
                    }
                }
                noCarWayBill.setFileBatchNum(fileBatchNum);

                //3.进行上传
                RespR respR = noCarService.noCarWaybillStart(noCarWayBill);
                if (respR.getCode() == 1) {
                    noCarWaybillMapperImprt.updateBillway(-2, respR.getMsg(), noCarWayBill);
                    stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append(respR.getMsg()).append("#");
                } else {
                    noCarWaybillMapperImprt.updateBillway(1, "", noCarWayBill);
                    return;
                }

            });

            log.error("开始平台指令上传失败NoCarBillWayServiceImpl.batchBillWayStart:{}", stringBuffer.toString());
            customerOperService.updateStatus(0,batchNumber);
        });

        return new RespR("批次号:" + batchNumber);
    }

    @Override
    public RespR batchHsitoryBillWay(List<NoCarWayBill> noCarWayBills, String customerName,String fileBatchNum) {
        if (!customerService.checkMoneyEnough(customerName)) {
            return new RespR(false, "余额不足");
        }
        StringBuffer stringBuffer = new StringBuffer();
        //保存批次号信息
        String batchNumber = customerOperService.saveCustomerOper(customerName, 3);
        executorService.execute(() -> {
            noCarWayBills.parallelStream().forEach(noCarWayBill -> {
                try {
                    log.info("开始处理历史运单：" + noCarWayBill.getBillNum());
                    //根据税号，查询备案企业
                    CustomerRec customerRec = new CustomerRec();
                    customerRec.setCustomerName(customerName);
                    customerRec.setCompanyReferencenum(noCarWayBill.getTaxplayerCode());
                    customerRec = customerRecMapper.selectByCustomerNameAndCompanyReference(customerRec);
                    noCarWayBill.setIntfaceStartTime(DateUtil.getCurrentDateStr());
                    noCarWayBill.setInterfaceEndTime(DateUtil.getCurrentDateStr());
                    noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
                    noCarWayBill.setBatchNum(batchNumber);
                    noCarWayBill.setTitleType(2);
                    noCarWayBill.setBillwayStatus(-2);
                    noCarWayBill.setHisFlag(1);
                    noCarWayBill.setCustomerName(customerName);
                    noCarWayBill.setContractType(1);//运单协议类型默认是 1
                    noCarWaybillMapperImprt.insertImport(noCarWayBill);
                    if (checkBatchHsitoryBillWay(stringBuffer, noCarWayBill, customerRec)) {
                        return;
                    }
                    if (checkCustomerCarRec(customerName, stringBuffer, noCarWayBill, customerRec)) {
                        return;
                    }
                    //3.kais指令上传
                    NoCarWayBill noCarWayBillClo = null;
                    try {
                        noCarWayBillClo = noCarWayBill.clone();
                    } catch (Exception e) {
                        e.printStackTrace();
                        noCarWayBillClo = noCarWayBill;
                    }
                    noCarWayBill.setFileBatchNum(fileBatchNum);
                    RespR respR = noCarService.noCarHisWaybillStart(noCarWayBill);
                    if (respR.getCode() == 1) {
                        stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append(respR.getMsg()).append("#");
                        noCarWaybillMapperImprt.updateBillway(-2, respR.getMsg(), noCarWayBill);
                        noCarWayBill.setBillwayStatus(-2);
                        noCarWayBill.setFailReason(respR.getMsg());
                        insertOrUpdateBillStart(noCarWayBill);
                        log.info(noCarWayBill.getBillNum() + "#开始指令失败" + respR.getMsg());
                    } else {
                        log.info(noCarWayBill.getBillNum() + "#开始指令成功" + respR.getMsg());
                        //3.kais指令上传
                        respR = noCarService.noCarHisWaybillEnd(noCarWayBillClo);

                        if (respR.getCode() == 1) {
                            noCarWaybillMapperImprt.updateBillway(-3, respR.getMsg(), noCarWayBill);
                            log.info(noCarWayBill.getBillNum() + "#结束指令失败" + respR.getMsg());
                            stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append(respR.getMsg()).append("#");
                        } else {
                            noCarWaybillMapperImprt.updateBillway(2, respR.getMsg(), noCarWayBill);
                            log.info(noCarWayBill.getBillNum() + "#结束指令成功" + respR.getMsg());
                        }
                    }
                    log.info("kai shi chu li li si yun dan" + noCarWayBill.getBillNum());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            customerOperService.updateStatus(0,batchNumber);
            if (!StringUtils.isEmpty(stringBuffer.toString())) {
                log.error(stringBuffer.toString());
            }
        });
        return new RespR("批次号:" + batchNumber);
    }

    private boolean checkCustomerCarRec(String customerName, StringBuffer stringBuffer, NoCarWayBill noCarWayBill, CustomerRec customerRec) {
        //1.查询是否有车辆备案 /
        CustomerCarRec customerCarRec;
        //2.无车车辆备案时进行车辆备案
        List<CustomerCarRec> customerCarRecs = new ArrayList<>();
        customerCarRec = new CustomerCarRec();
        customerCarRec.setCompanyName(noCarWayBill.getCompanyName());
        customerCarRec.setCarNum(noCarWayBill.getPlateNum());
        customerCarRec.setCarColor(noCarWayBill.getPlateColor());
        customerCarRec.setCompanyNum(customerRec.getCompanyNum());
        customerCarRec.setCustomerName(customerName);
        customerCarRec.setBusinessType("2");
        //默认运营车辆
        customerCarRec.setServiceOperation(1);
        //先查询上游是否已经备案
        RespR<VehicleQueryResponse> respRquery = noCarService.customerCarRecQueryUpper(customerCarRec);
        if (respRquery.getCode() == 1 || respRquery.getData() == null || respRquery.getData().getResult() == null || respRquery.getData().getResult().size() <= 0) {
            customerCarRecs.add(customerCarRec);
            RespR respR = noCarService.customerCarRec(customerCarRecs);
            if (respR.getCode() == 1) {
                noCarWaybillMapperImprt.updateBillway(-2, respR.getMsg(), noCarWayBill);
                stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append(respR.getMsg()).append("#");
                noCarWayBill.setBillwayStatus(-2);
                noCarWayBill.setFailReason(respR.getMsg());
                insertOrUpdateBillStart(noCarWayBill);
                return true;
            }
        }
        return false;
    }

    private boolean checkBatchHsitoryBillWay(StringBuffer stringBuffer, NoCarWayBill noCarWayBill, CustomerRec customerRec) {
        if (customerRec == null || customerRec.getRecStatus() != 1) {
            stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append("企业税号未备案#");
            noCarWaybillMapperImprt.updateBillway(-2, "企业税号未备案#", noCarWayBill);
            noCarWayBill.setBillwayStatus(-2);
            noCarWayBill.setFailReason("企业税号未备案");
            insertOrUpdateBillStart(noCarWayBill);
            return true;
        }
        noCarWayBill.setCompanyName(customerRec.getCompanyName());
        noCarWayBill.setCompanyNum(customerRec.getCompanyNum());
        if (DateUtil.getDistanceDays(noCarWayBill.getStartTime(), new Date()) > INTTOW) {
            log.info("历史运单开始上传失败：NoCarServiceImpl.noCarHisWaybillStart{},msg{}", noCarWayBill, "必须是二十天前的运单");
            noCarWayBill.setBillwayStatus(-2);
            noCarWayBill.setFailReason("失败，运单未满20天时效");
            noCarWaybillMapperImprt.updateBillway(-2, "失败，运单未满20天时效#", noCarWayBill);
            insertOrUpdateBillStart(noCarWayBill);
            return true;
        }
        if (DateUtil.getDistanceMills(noCarWayBill.getStartTime(), DateUtil.stringToDate(noCarWayBill.getPredictEndTime())) < INTTHREE*60 * 60 * 1000) {
            /*历史运单先不校验超时运单*/
            noCarWayBill.setSplitFlag(NoCarWayBill.SPLIT_FALG_TRUE);
        }
        return false;
    }

    @Override
    public RespR batchBillWayEnd(List<NoCarWayBill> noCarWayBills, String customerName) {
        log.error("结束平台指令上传数量NoCarBillWayServiceImpl.batchBillWayEnd:{}", noCarWayBills.size());
        if (!customerService.checkMoneyEnough(customerName)) {
            return new RespR(false, "余额不足");
        }
        if(customerOperService.countHasNotFinish(customerName)>0){
            return new RespR(false, "您账号下还有批量开始运单未执行完成，请等待执行完成再上传结束运单");
        }
        StringBuffer stringBuffer = new StringBuffer();

        //保存批次号信息
        String batchNumber = customerOperService.saveCustomerOper(customerName, 2);
        executorService.execute(() -> {
            noCarWayBills.parallelStream().forEach(noCarWayBill -> {
                try {
                    noCarWayBill.setBatchNum(batchNumber);
                    noCarWayBill.setBatchNumEnd(batchNumber);
                    noCarWayBill.setInterfaceEndTime(DateUtil.getCurrentDateStr());
                    noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
                    noCarWayBill.setHisFlag(0);
                    noCarWaybillMapperImprt.insertImport(noCarWayBill);
                    RespR respR = noCarService.noCarWaybillEnd(noCarWayBill);
                  //  noCarWayBill.setBillNum(batchNumber);
                    if (respR.getCode() == 1) {
                        noCarWaybillMapperImprt.updateBillway(-2, respR.getMsg(), noCarWayBill);
                        stringBuffer.append("#").append(noCarWayBill.getBillNum()).append(":").append(respR.getMsg()).append("#");
                    } else {
                        noCarWaybillMapperImprt.updateBillway(2, respR.getMsg(), noCarWayBill);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            });
            customerOperService.updateStatus(0,batchNumber);
            if (!StringUtils.isEmpty(stringBuffer.toString())) {
                log.error("开始平台指令上传失败NoCarBillWayServiceImpl.batchBillWayEnd:{}", stringBuffer.toString());
            }
        });
        return new RespR("批次号:" + batchNumber);
    }


    @Override
    public RespR findImportNocarBillWay(List<NoCarWayBill> noCarWayBills) {
        if (noCarWayBills == null || 0 == noCarWayBills.size()) {
            return new RespR<>("失败", "0");
        }
        List<NoCarWayBill> noCarWayBillsTmp = new ArrayList<NoCarWayBill>();
        for (NoCarWayBill noCarWayBill : noCarWayBills) {
            if (StringUtils.isEmpty(noCarWayBill.getBillNum())) {
                return new RespR<>("失败", "0");
            }
            NoCarWayBill bill = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
            noCarWayBillsTmp.add(bill);
        }
        return new RespR<>(noCarWayBillsTmp, "1");
    }

    @Override
    public RespR findImportNocarBillWayHis(List<NoCarWayBill> noCarWayBills) {
        if (noCarWayBills == null || 0 == noCarWayBills.size()) {
            return new RespR<>("失败", "0");
        }
        List<NoCarWayBill> noCarWayBillsTmp = new ArrayList<NoCarWayBill>();
        for (NoCarWayBill noCarWayBill : noCarWayBills) {
            if (StringUtils.isEmpty(noCarWayBill.getBillNum())) {
                return new RespR<>("失败", "0");
            }
            NoCarWayBill bill = noCarWaybillMapper.selectByBillNumHis(noCarWayBill.getBillNum());
            noCarWayBillsTmp.add(bill);
        }
        return new RespR<>(noCarWayBillsTmp, "1");
    }
}
