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

import cn.com.taiji.sdk.model.comm.protocol.tts.vehicle.VehicleQueryRequest;
import cn.com.taiji.sdk.model.comm.protocol.tts.vehicle.VehicleQueryResponse;
import cn.com.taiji.sdk.model.comm.protocol.tts.vehicle.VehicleRegisterRequest;
import cn.com.taiji.sdk.model.comm.protocol.tts.vehicle.VehicleRegisterResponse;
import cn.com.taiji.sdk.model.comm.protocol.tts.waybill.*;
import com.jkcredit.invoice.common.CommonConstants;
import com.jkcredit.invoice.mapper.binvoce.BillInvoiceMapper;
import com.jkcredit.invoice.mapper.calculateinfor.MounthAccMapper;
import com.jkcredit.invoice.mapper.calculateinfor.NoCarCalculateInforMapper;
import com.jkcredit.invoice.mapper.customer.CustomerCarRecMapper;
import com.jkcredit.invoice.mapper.customer.CustomerMapper;
import com.jkcredit.invoice.mapper.customer.CustomerRecMapper;
import com.jkcredit.invoice.mapper.waybill.NoCarWaybillMapper;
import com.jkcredit.invoice.model.entity.calculate.MounthAcc;
import com.jkcredit.invoice.model.entity.calculate.NoCarCalculateInfor;
import com.jkcredit.invoice.model.entity.customer.Customer;
import com.jkcredit.invoice.model.entity.customer.CustomerCarRec;
import com.jkcredit.invoice.model.entity.customer.CustomerRec;
import com.jkcredit.invoice.model.entity.invoice.BillInvoice;
import com.jkcredit.invoice.model.entity.manager.Param;
import com.jkcredit.invoice.model.entity.waybill.NoCarWayBill;
import com.jkcredit.invoice.service.lowerservice.NoCarService;
import com.jkcredit.invoice.service.lowerservice.vo.HCInvoiceQueryVo;
import com.jkcredit.invoice.service.lowerservice.vo.MonthAccountQueryVo;
import com.jkcredit.invoice.service.manager.ParamService;
import com.jkcredit.invoice.service.nocar.NoCarRecService;
import com.jkcredit.invoice.service.upService.NoCarInterface;
import com.jkcredit.invoice.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Repository("noCarService")
@Slf4j
public class NoCarServiceImpl implements NoCarService{

    
    
    @Autowired
    NoCarInterface noCarInterface;

    @Autowired
    NoCarWaybillMapper noCarWaybillMapper;

    @Autowired
    CustomerCarRecMapper customerCarRecMapper;

    @Autowired
    CustomerMapper customerMapper;

    @Autowired
    CustomerRecMapper customerRecMapper;

    @Autowired
    BillInvoiceMapper billInvoiceMapper;

    @Autowired
    NoCarCalculateInforMapper calculateInforMapper;

    @Autowired
    ParamService paramService;

    @Autowired
    NoCarRecService noCarRecService;

    @Override
    public RespR customerCarRec(List<CustomerCarRec> customerCarRecs) {
        log.info("车辆备案开始NoCarServiceImpl.customerCarRec{}",customerCarRecs);
        if(customerCarRecs== null || customerCarRecs.size()<=0){
            return new RespR(false,"无备案车辆");
        }
        StringBuffer res = new StringBuffer();
        CustomerCarRec customerCarRec2 = customerCarRecs.get(0);
        Customer customer = customerMapper.selectByCustomerName(customerCarRec2.getCustomerName());
        if(customer == null || customer.getAccstatus()!=0){
            res.append("#客户："+customerCarRec2.getCustomerName()+"不存在或状态异常");
            log.info("车辆备案异常NoCarServiceImpl.customerCarRec{},msg{}",customerCarRecs,res.toString());
            return new RespR(false,res.toString());
        }
        CustomerRec customerRecP = new CustomerRec();
        customerRecP.setCustomerName(customerCarRec2.getCustomerName());
        customerRecP.setCompanyName(customerCarRec2.getCompanyName());
        CustomerRec customerRec = customerRecMapper.selectByCustomerNameAndCompany(customerRecP);
        if(customerRec == null){
            res.append("#客户："+customerCarRec2.getCustomerName()+"企业:"+customerCarRec2.getCompanyName()+"备案信息不存在");
            log.info("车辆备案异常NoCarServiceImpl.customerCarRec{},msg{}",customerCarRecs,res.toString());
            return new RespR(false,res.toString());
        }
        return customerCarRecForNoCar(customerCarRecs,res,customerRec);
    }
    public  RespR customerCarRecForNoCar(List<CustomerCarRec> customerCarRecs, StringBuffer res, CustomerRec customerRec) {
        try {

            String respRResult = "";//上游成功返回结果
            for (CustomerCarRec customerCarRec : customerCarRecs) {
                if(!customerRec.getBussinessType().equals(customerCarRec.getBusinessType())){
                    res.append("#客户："+customerCarRec.getCustomerName()+"企业:"+customerCarRec.getCompanyName()+"车辆:"+customerCarRec.getCarNum()+"业务类型错误");
                    continue;
                }
                //先查询上游是否是已经备案
                VehicleQueryRequest vehicleQueryRequest = new VehicleQueryRequest();
                String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
                vehicleQueryRequest.setCompanyNum(companyNum);
                vehicleQueryRequest.setPlateColor(Integer.parseInt(customerCarRec.getCarColor()));
                vehicleQueryRequest.setPlateNum(customerCarRec.getCarNum());
                vehicleQueryRequest.setWaybillSource(1);


                //如果是接口，直接调用上游车辆备案
                if(0 != customerCarRec.getInterType() ){
                RespR<VehicleQueryResponse> respRB = noCarInterface.vehicleQuery(vehicleQueryRequest);
                if(respRB.getCode()!=1 && respRB.getData().getResult()!=null && respRB.getData().getResult().size()>0){
                    customerCarRec.setRecStatus(CommonConstants.REC_STATUS_SUC);
                    customerCarRec.setSuccTime(DateUtil.getCurrentDateStr());
                    //根据车牌号查询是新增还是更新
                    updateCustomerCarRec(customerCarRec);
                    continue;
                   }
                }
                //如果业务类型是无车
                VehicleRegisterRequest vehicleRegisterRequest = new VehicleRegisterRequest();
                if("0".equals(customerCarRec.getCarColor())){
                    if(customerCarRec.getServiceOperation() == null){
                        res.append("#客户："+customerCarRec.getCustomerName()+"企业:"+customerCarRec.getCompanyName()+"车辆:"+customerCarRec.getCarNum()+"为蓝牌车，请传入入运营类型");
                        continue;
                    }
                    vehicleRegisterRequest.setServiceOperation(customerCarRec.getServiceOperation());
                }
                vehicleRegisterRequest.setCompanyName(customerCarRec.getCompanyName());
                vehicleRegisterRequest.setCompanyNum(companyNum);
                vehicleRegisterRequest.setPlateColor(Integer.parseInt(customerCarRec.getCarColor()));
                vehicleRegisterRequest.setPlateNum(customerCarRec.getCarNum());
                RespR<VehicleRegisterResponse> respR = noCarInterface.vehicleRegister(vehicleRegisterRequest);
                if (respR.getCode() == 1) {
                    res.append(respR.getMsg());
                    customerCarRec.setRecStatus(CommonConstants.REC_STATUS_FAIL);
                    customerCarRec.setFailReason(respR.getMsg());
                    customerCarRec.setFailTime(DateUtil.getCurrentDateStr());
                } else {
                    respRResult = respR.getData().toString();//车辆备案成功
                    customerCarRec.setRecStatus(CommonConstants.REC_STATUS_SUC);
                    customerCarRec.setSuccTime(DateUtil.getCurrentDateStr());
                }
                //根据车牌号查询是新增还是更新
                updateCustomerCarRec(customerCarRec);

            }
            if(StringUtils.isEmpty(res.toString())){
                log.info("车辆备案成功");
                return new RespR(respRResult);
            }else {
                log.info("车辆备案异常NoCarServiceImpl.customerCarRec{},msg{}",customerCarRecs,res.toString());
                return new RespR(false,res.toString());
            }

        }catch (Exception e){
            e.printStackTrace();
            return new RespR(false,e.getMessage());
        }

    }

    @Override
    public RespR customerCarRecQueryUpper(CustomerCarRec customerCarRec) {
        StringBuffer res = new StringBuffer();
        log.info("车辆备案查询NoCarServiceImpl.customerCarRecQueryUpper{}",customerCarRec);
        Customer customer = customerMapper.selectByCustomerName(customerCarRec.getCustomerName());
        if(customer == null || customer.getAccstatus()!=0){
            res.append("#客户："+customer.getCustomerName()+"不存在或状态异常");
            return new RespR(false,res.toString());
        }

        VehicleQueryRequest vehicleQueryRequest = new VehicleQueryRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        vehicleQueryRequest.setCompanyNum(companyNum);
        vehicleQueryRequest.setWaybillSource(1);//1 无车承运人
        vehicleQueryRequest.setPlateNum(customerCarRec.getCarNum());
        vehicleQueryRequest.setPlateColor(Integer.valueOf(customerCarRec.getCarColor()));

        RespR<VehicleQueryResponse> respR = noCarInterface.vehicleQuery(vehicleQueryRequest);
        if(respR.getCode() == 1){
            log.info("车辆备案查询失败NoCarServiceImpl.customerCarRecQueryUpper{},msg{}",customerCarRec,respR.getMsg());
        }else if(8 != customerCarRec.getInterType()){//此处表示仅适用接口查询，不走业务逻辑
            customerCarRec.setRecStatus(1);
            updateCustomerCarRec(customerCarRec);
        }
        return respR;
    }

    public  void updateCustomerCarRec(CustomerCarRec customerCarRec){
        //根据车牌号查询是新增还是更新
        List<CustomerCarRec> customerCarRec1 = customerCarRecMapper.selectByCarNum(customerCarRec.getCarNum());
        if (customerCarRec1 == null || customerCarRec1.size()==0) {
            customerCarRecMapper.insert(customerCarRec);
        } else {
            customerCarRecMapper.updateByPrimaryKey(customerCarRec);
        }
    }


    @Override
    public RespR customerCarRecQuery(CustomerCarRec customerCarRec) {

        return new RespR(customerCarRecMapper.selectByCustName(customerCarRec.getCustomerName()));
    }

    @Override
    public RespR noCarWaybillStart(NoCarWayBill noCarWayBill) {
        log.info("运单上传开始：NoCarServiceImpl.noCarWaybillStart{}",noCarWayBill);
        NoCarWayBill noCarWayBillDb = null;
        try {
            noCarWayBillDb = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        }catch (Exception e){
            return new RespR(false,"有重复运单，请联系管理员删除");
        }
        if(noCarWayBillDb!=null && noCarWayBillDb.getBillwayStatus()>0){
            return new   RespR(false,"开始指令已经上传成功");
        }
        //如果运单时间和当前时间差了三天，直接返回
        if(DateUtil.getDistanceHours(noCarWayBill.getStartTime(),new Date())<-72){
            noCarWayBill.setFailReason("失败，运单开始时间超72小时");
            noCarWayBill.setBillwayStatus(-2);
            insertOrUpdateBillStart(noCarWayBill);
            return new RespR(false,"失败，运单开始时间超72小时");
        }
        RespR respR = checkCarWayBillAndSetInfo(noCarWayBill);
        if(respR.getCode() == 1){
            log.info("运单上传失败：NoCarServiceImpl.noCarWaybillStart{}，msg{}",noCarWayBill,respR.getMsg());
            noCarWayBill.setFailReason(respR.getMsg());
            noCarWayBill.setBillwayStatus(-2);
            insertOrUpdateBillStart(noCarWayBill);
            return  respR;
        }
        WaybillStartRequest waybillStartRequest = buildWaybillStartRequest(noCarWayBill);
        RespR<WaybillStartResponse> responseRespR = noCarInterface.waybillStart(waybillStartRequest);
        if(responseRespR.getCode() == 1){
            log.info("运单上传失败：NoCarServiceImpl.noCarWaybillStart{}，msg{}",noCarWayBill,responseRespR.getMsg());
            noCarWayBill.setFailReason(responseRespR.getMsg());
            noCarWayBill.setBillwayStatus(-2);
            insertOrUpdateBillStart(noCarWayBill);
            return new RespR(false,responseRespR.getMsg());
        }else{
            noCarWayBill.setBillwayStatus(1);
            insertOrUpdateBillStart(noCarWayBill);
        }
        return new RespR(responseRespR.getData());
    }
    //插入或者更新运单
    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);
        }
    }
    /**
     * 组装指令报文
     */
    public WaybillStartRequest buildWaybillStartRequest(NoCarWayBill noCarWayBill){
        WaybillStartRequest waybillStartRequest = new WaybillStartRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillStartRequest.setCompanyNum(companyNum);
        waybillStartRequest.setNum(noCarWayBill.getBillNum());
        waybillStartRequest.setPlateNum(noCarWayBill.getPlateNum());
        waybillStartRequest.setPlateColor(Integer.parseInt(noCarWayBill.getPlateColor()));
        waybillStartRequest.setStartTime(DateUtil.dateFormate(noCarWayBill.getStartTime()));
        waybillStartRequest.setSourceAddr(noCarWayBill.getSourceAddr());
        waybillStartRequest.setDestAddr(noCarWayBill.getDestAddr());
        waybillStartRequest.setPredictEndTime(DateUtil.dateFormate(noCarWayBill.getPredictEndTime()));
        waybillStartRequest.setFee(noCarWayBill.getFee());
        waybillStartRequest.setTitleType(noCarWayBill.getTitleType());
        waybillStartRequest.setTaxplayerCode(noCarWayBill.getTaxplayerCode());
        waybillStartRequest.setName(noCarWayBill.getCompanyName());
        waybillStartRequest.setAddress(noCarWayBill.getCompanyAdress());
        waybillStartRequest.setTel(noCarWayBill.getCompanyTel());
        waybillStartRequest.setBank(noCarWayBill.getCompanyBank());
        waybillStartRequest.setBankAccount(noCarWayBill.getCompanyBankAcc());
        waybillStartRequest.setCompanyName(noCarWayBill.getCompanyName());
        return waybillStartRequest;
    }
    public RespR checkCarWayBillAndSetInfo(NoCarWayBill noCarWayBill){
        try {
            Customer customer = customerMapper.selectByCustomerName(noCarWayBill.getCustomerName());
            if(customer==null || customer.getAccstatus() ==1){
                return new RespR(false,"客户不存在或者已经停用");
            }
            CustomerRec customerRecParm = new CustomerRec();
            customerRecParm.setCompanyName(noCarWayBill.getCompanyName());
            customerRecParm.setCustomerName(noCarWayBill.getCustomerName());
            CustomerRec customerRec = customerRecMapper.selectByCustomerNameAndCompany(customerRecParm);
            if(customerRec == null || customerRec.getRecStatus()!=1){
                return new RespR(true);//
            }
            noCarWayBill.setCompanyNum(customerRec.getCompanyNum());
            noCarWayBill.setCompanyAdress(customerRec.getCompanyAdress());
            noCarWayBill.setCompanyTel(customerRec.getCompanyPhone());
            noCarWayBill.setCompanyBank(customerRec.getCompanyOpenbank());
            noCarWayBill.setCompanyBankAcc(customerRec.getCompanyOpenbankAcc());
        }catch (Exception e){
            e.printStackTrace();
            log.info("运单企业信息设置错误{}",noCarWayBill);
            return new RespR(false,"运单企业信息设置错误"+e.getMessage());
        }

        return new RespR();
    }
    @Override
    public RespR noCarWaybillEnd(NoCarWayBill noCarWayBill) {
        log.info("运单结束开始：NoCarServiceImpl.noCarWaybillEnd{}",noCarWayBill);
        NoCarWayBill noCarWayBillDb = null;
        try {
            noCarWayBillDb = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        }catch (Exception e){
            return new RespR(false,"有重复运单，请联系管理员删除");
        }
        if(noCarWayBillDb == null){
            try{
                noCarWayBillDb = (NoCarWayBill)noCarWayBill.clone();
            }catch (Exception e){
                e.printStackTrace();
                return new RespR(false,"系统异常，请重试");
            }

        }
        if(noCarWayBillDb.getBillwayStatus() >1 ){
            return new RespR(false,"运单已经结束或者是历史已结束运单，请联系管理员确认");
        }
        noCarWayBillDb.setPreEndTime(noCarWayBillDb.getPredictEndTime());
        noCarWayBillDb.setDestAddrPre(noCarWayBillDb.getDestAddr());
        noCarWayBillDb.setDestAddr(noCarWayBill.getDestAddr());
        noCarWayBillDb.setPredictEndTime(noCarWayBill.getPredictEndTime());
        noCarWayBillDb.setBatchNumEnd(noCarWayBill.getBatchNumEnd());
        noCarWayBillDb.setInterType(noCarWayBill.getInterType());

        WaybillEndRequest waybillEndRequest = new WaybillEndRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillEndRequest.setCompanyNum(companyNum);
        waybillEndRequest.setNum(noCarWayBillDb.getBillNum());
        waybillEndRequest.setRealDestAddr(noCarWayBillDb.getDestAddr());
        waybillEndRequest.setEndTime(DateUtil.dateFormate(noCarWayBillDb.getPredictEndTime()));
        RespR<WaybillEndResponse> waybillEndResponseRespR = noCarInterface.waybillEnd(waybillEndRequest);
        if(waybillEndResponseRespR.getCode() == 1){
            log.info("运单结束失败：NoCarServiceImpl.noCarWaybillEnd{},msg{}",noCarWayBill,waybillEndResponseRespR.getMsg());
            noCarWayBillDb.setBillwayStatus(-3);
            noCarWayBillDb.setFailReason(waybillEndResponseRespR.getMsg());
            insertOrUpdateBillEnd(noCarWayBillDb);
            return new RespR(false,waybillEndResponseRespR.getMsg());
        }else if("4".equals(waybillEndResponseRespR.getData().getInfo())){
            log.info("运单结束失败：NoCarServiceImpl.noCarWaybillEnd{},msg{}",noCarWayBill,"运单已经超时");
            noCarWayBillDb.setBillwayStatus(4);
            noCarWayBillDb.setFailReason(waybillEndResponseRespR.getMsg());
            insertOrUpdateBillEnd(noCarWayBillDb);
            return new RespR(false,"运单已经超时");
        }
        noCarWayBillDb.setInterfaceEndTime(DateUtil.getCurrentDateStr());
        noCarWayBillDb.setBillwayStatus(2);
        noCarWayBillDb.setUpdateTime(DateUtil.getCurrentDateStr());
        insertOrUpdateBillEnd(noCarWayBillDb);
        return new RespR(waybillEndResponseRespR.getData());
    }
    //插入或者更新运单
    public void insertOrUpdateBillEnd(NoCarWayBill noCarWayBill){
        noCarWayBill.setInterfaceEndTime(DateUtil.getCurrentDateStr());
        noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
        NoCarWayBill curr = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        if(curr == null){
            noCarWaybillMapper.insert(noCarWayBill);
        }else{
            if(curr.getBillwayStatus()>1){
                return;
            }
            noCarWaybillMapper.updateByBillNum(noCarWayBill);
        }
    }
    //插入或者更新运单
    public void insertOrUpdateBill(NoCarWayBill noCarWayBill){
        noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
        NoCarWayBill curr = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        if(curr == null){
            noCarWaybillMapper.insert(noCarWayBill);
        }else{
            if(curr.getBillwayStatus()>2){
                return;
            }
            noCarWaybillMapper.updateByBillNum(noCarWayBill);
        }
    }
    @Override
    public RespR noCarHisWaybillStart(NoCarWayBill noCarWayBill) {
        log.info("历史运单开始上传：NoCarServiceImpl.noCarHisWaybillStart{},msg{}",noCarWayBill,"开始");
        NoCarWayBill noCarWayBillDb = null;
        try {
            noCarWayBillDb = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        }catch (Exception e){
            return new RespR(false,"有重复运单，请联系管理员删除");
        }
        if(noCarWayBillDb!=null && noCarWayBillDb.getBillwayStatus()>0){
            return new   RespR(false,"开始指令已经上传成功,请勿重复上传");
        }
        if(DateUtil.getDistanceDays(noCarWayBill.getStartTime(),new Date())>-20){
            log.info("历史运单开始上传失败：NoCarServiceImpl.noCarHisWaybillStart{},msg{}",noCarWayBill,"必须是二十天前的运单");
            noCarWayBill.setBillwayStatus(-2);
            noCarWayBill.setFailReason("失败，运单未满20天时效");
            insertOrUpdateBillStart(noCarWayBill);
            return new RespR(false,"失败，运单未满20天时效");
        }

        RespR respR = checkCarWayBillAndSetInfo(noCarWayBill);
        if(respR.getCode() == 1){
            log.info("历史运单开始上传失败：NoCarServiceImpl.noCarHisWaybillStart{},msg{}",noCarWayBill,respR.getMsg());
            noCarWayBill.setBillwayStatus(-2);
            noCarWayBill.setFailReason(respR.getMsg());
            insertOrUpdateBillStart(noCarWayBill);
            return  respR;
        }
        WaybillHistoryStartRequest waybillHistoryStartRequest = BuildNoCarHisWaybill(noCarWayBill);
        RespR<WaybillHistoryStartResponse> responseRespR = noCarInterface.waybillHistoryStart(waybillHistoryStartRequest);

        if(responseRespR.getCode() == 1){
            log.info("历史运单开始上传失败：NoCarServiceImpl.noCarHisWaybillStart{},msg{}",noCarWayBill,responseRespR.getMsg());
            noCarWayBill.setBillwayStatus(-2);
            noCarWayBill.setFailReason(responseRespR.getMsg());
            insertOrUpdateBillStart(noCarWayBill);
            return new RespR(false,responseRespR.getMsg());
        }else{
            noCarWayBill.setIntfaceStartTime(DateUtil.getCurrentDateStr());
            noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
            noCarWayBill.setBillwayStatus(1);
            insertOrUpdateBillStart(noCarWayBill);
        }
        return new RespR(responseRespR.getData());
    }

    public WaybillHistoryStartRequest BuildNoCarHisWaybill(NoCarWayBill noCarWayBill){
        WaybillHistoryStartRequest waybillStartRequest = new WaybillHistoryStartRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillStartRequest.setCompanyNum(companyNum);
        waybillStartRequest.setNum(noCarWayBill.getBillNum());
        waybillStartRequest.setPlateNum(noCarWayBill.getPlateNum());
        waybillStartRequest.setPlateColor(Integer.parseInt(noCarWayBill.getPlateColor()));
        waybillStartRequest.setStartTime(DateUtil.dateFormate(noCarWayBill.getStartTime()));
        waybillStartRequest.setSourceAddr(noCarWayBill.getSourceAddr());
        waybillStartRequest.setDestAddr(noCarWayBill.getDestAddr());
        waybillStartRequest.setPredictEndTime(DateUtil.dateFormate(noCarWayBill.getPredictEndTime()));
        waybillStartRequest.setFee(noCarWayBill.getFee());
        waybillStartRequest.setTitleType(noCarWayBill.getTitleType());
        waybillStartRequest.setTaxplayerCode(noCarWayBill.getTaxplayerCode());
        waybillStartRequest.setName(noCarWayBill.getCompanyName());
        waybillStartRequest.setAddress(noCarWayBill.getCompanyAdress());
        waybillStartRequest.setTel(noCarWayBill.getCompanyTel());
        waybillStartRequest.setBank(noCarWayBill.getCompanyBank());
        waybillStartRequest.setBankAccount(noCarWayBill.getCompanyBankAcc());
        return waybillStartRequest;
    }
    @Override
    public RespR noCarHisWaybillEnd(NoCarWayBill noCarWayBill) {
        NoCarWayBill noCarWayBillDb = null;
        try {
            noCarWayBillDb = noCarWaybillMapper.selectByBillNum(noCarWayBill.getBillNum());
        }catch (Exception e){
            return new RespR(false,"有重复运单，请联系管理员删除");
        }
        if(noCarWayBillDb == null){
            try{
                noCarWayBillDb = (NoCarWayBill)noCarWayBill.clone();
            }catch (Exception e){
                e.printStackTrace();
                return new RespR(false,"系统异常，请重试");
            }

        }
        log.info("历史运单结束上传：NoCarServiceImpl.noCarHisWaybillEnd{},msg{}",noCarWayBill,"开始");
        if(noCarWayBillDb.getBillwayStatus()>1){
            return new RespR(false,"结束运单已经上传，无需再次上传");
        }
        noCarWayBillDb.setPreEndTime(noCarWayBillDb.getPredictEndTime());
        noCarWayBillDb.setDestAddrPre(noCarWayBillDb.getDestAddr());
        noCarWayBillDb.setDestAddr(noCarWayBill.getDestAddr());
        noCarWayBillDb.setPredictEndTime(noCarWayBill.getPredictEndTime());
        noCarWayBillDb.setInterType(noCarWayBill.getInterType());
        WaybillHistoryEndRequest waybillEndRequest = new WaybillHistoryEndRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillEndRequest.setCompanyNum(companyNum);
        waybillEndRequest.setNum(noCarWayBillDb.getBillNum());
        waybillEndRequest.setRealDestAddr(noCarWayBillDb.getDestAddr());
        waybillEndRequest.setEndTime(DateUtil.dateFormate(noCarWayBillDb.getPredictEndTime()));
        RespR<WaybillHistoryEndResponse> waybillEndResponseRespR = noCarInterface.waybillHistoryEnd(waybillEndRequest);
        if(waybillEndResponseRespR.getCode() == 1){
            noCarWayBillDb.setBillwayStatus(-3);
            noCarWayBillDb.setFailReason(waybillEndResponseRespR.getMsg());
            insertOrUpdateBillEnd(noCarWayBillDb);
            log.info("历史运单结束上传失败：NoCarServiceImpl.noCarHisWaybillEnd{},msg{}",noCarWayBillDb,waybillEndResponseRespR.getMsg());

            return new RespR(false,waybillEndResponseRespR.getMsg());
        }else if("4".equals(waybillEndResponseRespR.getData().getInfo())){
            noCarWayBill.setBillwayStatus(4);
            insertOrUpdateBillEnd(noCarWayBillDb);
            log.info("历史运单结束上传失败：NoCarServiceImpl.noCarHisWaybillEnd{},msg{}",noCarWayBillDb,"运单已经超时，请拆分");
            return new RespR(false,"运单已经超时");
        }
        noCarWayBillDb.setBillwayStatus(2);
        insertOrUpdateBillEnd(noCarWayBillDb);
        return new RespR(waybillEndResponseRespR.getData());
    }
    public WaybillNumFindInvoiceResponse buildInterFaceVoiceData(NoCarWayBill noCarWayBill,List<BillInvoice> billInvoices){
        WaybillNumFindInvoiceResponse waybillNumFindInvoiceResponse = new WaybillNumFindInvoiceResponse();
        List<InvoiceProcessingListModel> invoiceProcessingListModels = new ArrayList<>();
        waybillNumFindInvoiceResponse.setResult(invoiceProcessingListModels);
        waybillNumFindInvoiceResponse.setPlateNum(noCarWayBill.getPlateNum());
        waybillNumFindInvoiceResponse.setInfo("成功");
        waybillNumFindInvoiceResponse.setWaybillStartTime(noCarWayBill.getStartTime()==null?null:DateUtil.dateToTime(noCarWayBill.getStartTime()));
        waybillNumFindInvoiceResponse.setWaybillEndTime(noCarWayBill.getPredictEndTime()==null?null:DateUtil.dateToTime(noCarWayBill.getPredictEndTime()));
        waybillNumFindInvoiceResponse.setWaybillStatus(noCarWayBill.getBillwayStatus());
        waybillNumFindInvoiceResponse.setReceiveTime(DateUtil.dateToTime(DateUtil.getCurrentDateStr()));
        waybillNumFindInvoiceResponse.setWaybillNum(noCarWayBill.getBillNum());
        if(billInvoices != null && billInvoices.size()>0){
            billInvoices.stream().forEach(billInvoice -> {
                InvoiceProcessingListModel invoiceProcessingListModel = new InvoiceProcessingListModel();
                BeanUtils.copyProperties(billInvoice,invoiceProcessingListModel);
                invoiceProcessingListModel.setExTime(DateUtil.dateToTime(invoiceProcessingListModel.getExTime()));
                invoiceProcessingListModel.setInvoiceMakeTime(DateUtil.dateToTime(invoiceProcessingListModel.getInvoiceMakeTime()));
                invoiceProcessingListModel.setTradeMatchTime(DateUtil.dateToTime(invoiceProcessingListModel.getTradeMatchTime()));
                invoiceProcessingListModel.setWaybillStartTime(DateUtil.dateToTime(invoiceProcessingListModel.getWaybillStartTime()));
                invoiceProcessingListModel.setWaybillEndTime(DateUtil.dateToTime(invoiceProcessingListModel.getWaybillEndTime()));
                invoiceProcessingListModels.add(invoiceProcessingListModel);
            });
        }
        return waybillNumFindInvoiceResponse;
    }
    @Override
    @Transactional(isolation= Isolation.READ_COMMITTED)
    public RespR getInvoiceByWayBillNumReal(NoCarWayBill noCarWayBill, boolean isInterface) {
        byte isKf = 1;
        /**
         * 迁移数据
         */
        if(noCarWayBill.getInterType() == 3){
            isKf = 3;
        }
        /**
         * 特殊处理数据
         */
        if(noCarWayBill.getInterType() == 5){
            isKf = 5;
        }
        log.info("取票啦：NoCarServiceImpl.getInvoiceByWayBillNumReal{},isCurr{}",noCarWayBill,isInterface);
        if(isInterface && (noCarWayBill.getBillwayStatus()!=-5 || noCarWayBill.getInterType() == 4)){
            if(noCarWayBill.getBillwayStatus() == 1 || noCarWayBill.getBillwayStatus() == 2 || noCarWayBill.getBillwayStatus() == 3 || noCarWayBill.getBillwayStatus() == 4){
                //直接返回发票信息
                List<BillInvoice> billInvoices = billInvoiceMapper.selectByBillNum(noCarWayBill.getBillNum());
                WaybillNumFindInvoiceResponse waybillNumFindInvoiceResponse = buildInterFaceVoiceData(noCarWayBill,billInvoices);
                return new RespR(waybillNumFindInvoiceResponse);
            }else{
                return new RespR(false,noCarWayBill.getFailReason()==null?"运单未知异常":noCarWayBill.getFailReason());
            }
        }
        if(noCarWayBill.getBillwayStatus()!=2 && noCarWayBill.getBillwayStatus()!=-5){
           return new RespR(false,"不是开票中的状态，别取票啦");
        }
        RespR respR = checkCarWayBillAndSetInfo(noCarWayBill);
        if(respR.getCode() == 1){
            log.info("取票失败啦：NoCarServiceImpl.getInvoiceByWayBillNumReal{},isCurr{},msg{}",noCarWayBill,isInterface,respR.getMsg());
            return  respR;
        }

        //进行取票操作
        WaybillNumFindInvoiceRequest waybillNumFindInvoiceRequest = new WaybillNumFindInvoiceRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillNumFindInvoiceRequest.setCompanyNum(companyNum);
        waybillNumFindInvoiceRequest.setWaybillNum(noCarWayBill.getBillNum());
        RespR<WaybillNumFindInvoiceResponse> responseRespR = noCarInterface.waybillNumFindInvoice(waybillNumFindInvoiceRequest);
        if(responseRespR.getCode() == 1){
            log.info("取票失败啦：NoCarServiceImpl.getInvoiceByWayBillNumReal{},isCurr{},msg{}",noCarWayBill,isInterface,responseRespR.getMsg());
            return new RespR(false,responseRespR.getMsg());
        }else{
            int tempStatus = responseRespR.getData().getWaybillStatus().intValue();
            if(noCarWayBill.getBillwayStatus()==-5){
                if(isKf != 3){
                    noCarWayBill.setInterType(0);
                }else{
                    if(tempStatus == 3){
                        noCarWayBill.setInterType(4);
                    }
                }
                noCarWayBill.setPlateNum(responseRespR.getData().getPlateNum());
                noCarWayBill.setStartTime(DateUtil.tTimeToDate(responseRespR.getData().getWaybillStartTime()));
                noCarWayBill.setPredictEndTime(DateUtil.tTimeToDate(responseRespR.getData().getWaybillEndTime()));
                //更改票状态
                noCarWayBill.setBillwayStatus(tempStatus);
                insertOrUpdateBill(noCarWayBill);
            }else {
                //更改票状态
                noCarWayBill.setPlateNum(responseRespR.getData().getPlateNum());
                noCarWayBill.setStartTime(DateUtil.tTimeToDate(responseRespR.getData().getWaybillStartTime()));
                noCarWayBill.setPredictEndTime(DateUtil.tTimeToDate(responseRespR.getData().getWaybillEndTime()));
                noCarWayBill.setBillwayStatus(tempStatus);
                noCarWayBill.setUpdateTime(DateUtil.getCurrentDateStr());
                noCarWaybillMapper.updateByBillNum(noCarWayBill);
            }

            if(tempStatus == 2 || tempStatus==3){
                //删除已有发票
                billInvoiceMapper.deleteByBillNum(noCarWayBill.getBillNum());
                //发票入库
                List<InvoiceProcessingListModel> invoiceProcessingListModels = responseRespR.getData().getResult();
                //用set来去重计费信息
                Set<NoCarCalculateInfor> carCalculateInfors = new HashSet<>();
                invoiceProcessingListModels.stream().forEach(invoiceProcessingListModel -> {
                    BillInvoice billInvoice = buildFromInvoiceProcessingListModel(invoiceProcessingListModel);
                    billInvoice.setCompanyName(noCarWayBill.getCompanyName());
                    billInvoice.setCompanyNum(noCarWayBill.getCompanyNum());
                    billInvoice.setCustomerName(noCarWayBill.getCustomerName());
                    //扣费明细入账
                    NoCarCalculateInfor calculateInfor = new NoCarCalculateInfor();
                    if(noCarWayBill.getInterType()!=4 && noCarWayBill.getInterType()!=3){
                        calculateInfor.setCalculateTime(DateUtil.getCurrentDateStr());
                    }else{
                        calculateInfor.setCalculateTime("2021-01-11 00:00:00");
                    }

                    calculateInfor.setCompanyNum(noCarWayBill.getCompanyNum());
                    calculateInfor.setCtype(1);
                    calculateInfor.setCustomId(noCarWayBill.getCustomerName());
                    calculateInfor.setBuyerName(invoiceProcessingListModel.getBuyerName());
                    calculateInfor.setBuyerTaxpayerCode(invoiceProcessingListModel.getBuyerTaxpayerCode());
                    calculateInfor.setInvoiceMakeTime(billInvoice.getInvoiceMakeTime());
                    calculateInfor.setTradeId(billInvoice.getTransactionId());
                    NoCarCalculateInfor noCarCalculateInfor = calculateInforMapper.selectByTradeId(billInvoice.getTransactionId());
                    if(noCarCalculateInfor!=null){
                        billInvoice.setCalculateTime(noCarCalculateInfor.getCalculateTime());
                    }else{
                        carCalculateInfors.add(calculateInfor);
                        billInvoice.setCalculateTime(calculateInfor.getCalculateTime());
                    }

                    billInvoiceMapper.insert(billInvoice);
                });
                if(isKf == 3)   return new RespR(responseRespR.getData());
                //统一插入交易id 和 和计费信息
                Param param = paramService.getParamsByParamName("CUST_NOCAR_FEE");
                Double fee = Double.parseDouble(param.getParamValue());
                Customer customer = customerMapper.selectByCustomerNameForLock(noCarWayBill.getCustomerName());
                customer.setInvoiceTime(DateUtil.getCurrentDateStr());
                carCalculateInfors.stream().forEach(calculateInfor -> {
                    try {
                        calculateInfor.setCompanyLongName(customer.getCompany());
                        calculateInfor.setFee(fee);
                        calculateInforMapper.insert(calculateInfor);
                        customer.setAccountBalance(MathUtil.sub(customer.getAccountBalance(),calculateInfor.getFee()));
                    }catch (Exception e){
                        log.error("重复数据来啦"+calculateInfor.getTradeId());
                    }


                });
                if(isKf==1)
                customerMapper.updateByPrimaryKeySelective(customer);

            }
            if(isInterface){
                return new RespR(responseRespR.getData());
            }
        }
        return new RespR("success");
    }
    public BillInvoice buildFromInvoiceProcessingListModel(InvoiceProcessingListModel invoiceProcessingListModel){
        BillInvoice billInvoice = new BillInvoice();
        BeanUtils.copyProperties(invoiceProcessingListModel,billInvoice);
        //设置时间
        billInvoice.setExTime(DateUtil.tTimeToDate(billInvoice.getExTime()));
        billInvoice.setInvoiceMakeTime(DateUtil.tTimeToDate(billInvoice.getInvoiceMakeTime()));
        billInvoice.setWaybillEndTime(DateUtil.tTimeToDate(billInvoice.getWaybillEndTime()));
        billInvoice.setTradeMatchTime(DateUtil.tTimeToDate(billInvoice.getTradeMatchTime()));
        billInvoice.setWaybillStartTime(DateUtil.tTimeToDate(billInvoice.getWaybillStartTime()));
        return billInvoice;
    }

    @Override
    public RespR hCInvoiceQuery(HCInvoiceQueryVo hcInvoiceQueryVo) {
        log.info("取红冲票啦：NoCarServiceImpl.hCInvoiceQuery{}",hcInvoiceQueryVo);
        WaybillInvoiceRedQueryRequest redQueryRequest = new WaybillInvoiceRedQueryRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        redQueryRequest.setCompanyNum(companyNum);
        redQueryRequest.setMonth(hcInvoiceQueryVo.getMonth());

        RespR<WaybillInvoiceRedQueryResponse> respR = noCarInterface.waybillInvoiceRedQuery(redQueryRequest);
        if(respR.getCode() == 1){
            log.info("取红冲票失败啦：NoCarServiceImpl.hCInvoiceQuery{},msg{}",hcInvoiceQueryVo,respR.getMsg());
            return new RespR(false,respR.getMsg());
        }
            return respR;
    }
    @Override
    public RespR monthAccQuery(MonthAccountQueryVo monthAccountQueryVo) {
        log.info("取月票啦：NoCarServiceImpl.monthAccQuery{},msg{}",monthAccountQueryVo,"开始");
        CustomerRec customerRecParm = new CustomerRec();
        customerRecParm.setCompanyName(monthAccountQueryVo.getCompanyName());
        customerRecParm.setCustomerName(monthAccountQueryVo.getCustomeName());
        CustomerRec customerRec = null;
        List<CustomerRec> customerRecs = customerRecMapper.selectByCompanyName(monthAccountQueryVo.getCompanyName());
        if(customerRecs != null && customerRecs.size()>0){
            customerRec = customerRecs.get(0);
        }
        if(customerRec == null || customerRec.getRecStatus()!=1){
            log.info("取月票失败啦：NoCarServiceImpl.monthAccQuery{},msg{}",monthAccountQueryVo,"企业未备案成功,查询失败");
            return new RespR(false,"企业未备案成功,查询失败");
        }
        WaybillCountQueryRequest waybillCountQueryRequest = new WaybillCountQueryRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillCountQueryRequest.setCompanyNum(companyNum);
        waybillCountQueryRequest.setTaxCode(customerRec.getCompanyReferencenum());
        waybillCountQueryRequest.setTradeMonth(monthAccountQueryVo.getTradeMonth());
        waybillCountQueryRequest.setWaybillSource(monthAccountQueryVo.getWaybillSource());
        waybillCountQueryRequest.setPageNo(monthAccountQueryVo.getPageNo());
        waybillCountQueryRequest.setPageSize(1000);
        RespR<WaybillCountQueryResponse> waybillCountQueryResponseRespR =  noCarInterface.waybillCountQuery(waybillCountQueryRequest);
        log.info("取月票结束：NoCarServiceImpl.monthAccQuery{},msg{}",waybillCountQueryResponseRespR,waybillCountQueryResponseRespR.getMsg());
        return waybillCountQueryResponseRespR;
    }
    @Autowired
    MounthAccMapper mounthAccMapper;
    @Override
    public RespR monthAccQueryUpdate(MonthAccountQueryVo monthAccountQueryVo) {
        log.info("更新取月票啦：NoCarServiceImpl.monthAccQueryUpdate{},msg{}",monthAccountQueryVo,"开始");
        CustomerRec customerRecParm = new CustomerRec();
        customerRecParm.setCompanyName(monthAccountQueryVo.getCompanyName());
        customerRecParm.setCustomerName(monthAccountQueryVo.getCustomeName());
        CustomerRec customerRec = null;
        List<CustomerRec> customerRecs = customerRecMapper.selectByCompanyName(monthAccountQueryVo.getCompanyName());
        if(customerRecs != null && customerRecs.size()>0){
            for(CustomerRec customerRec1:customerRecs){
                if("2".equals(customerRec1.getBussinessType())){
                    customerRec = customerRec1 ;
                    break;
                }
            }
        }

        if(customerRec == null || customerRec.getRecStatus()!=1){
            log.info("取月票失败啦：NoCarServiceImpl.hCInvoiceQuery{},msg{}",monthAccountQueryVo,"企业未备案成功,查询失败");
            return new RespR(false,"企业未备案成功,查询失败");
        }
        WaybillCountQueryRequest waybillCountQueryRequest = new WaybillCountQueryRequest();
        String companyNum = paramService.getParamsByParamName("REQUEST_COMPANY_NUM").getParamValue();
        waybillCountQueryRequest.setCompanyNum(companyNum);
        waybillCountQueryRequest.setTaxCode(customerRec.getCompanyReferencenum());
        waybillCountQueryRequest.setTradeMonth(monthAccountQueryVo.getTradeMonth());
        waybillCountQueryRequest.setWaybillSource(monthAccountQueryVo.getWaybillSource());
        waybillCountQueryRequest.setPageNo(monthAccountQueryVo.getPageNo());
        waybillCountQueryRequest.setPageSize(1000);
        RespR<WaybillCountQueryResponse> waybillCountQueryResponseRespR =  noCarInterface.waybillCountQuery(waybillCountQueryRequest);
        if(waybillCountQueryResponseRespR.getCode() != 1){
            dealMouthAcc(waybillCountQueryResponseRespR,customerRec);
            log.info(waybillCountQueryResponseRespR.getData().getTotalCount()+"---hehhe----"+monthAccountQueryVo.getCompanyName());
            if(waybillCountQueryResponseRespR.getData().getTotalCount()>1000){
                long pages = waybillCountQueryResponseRespR.getData().getTotalCount()%1000==0?waybillCountQueryResponseRespR.getData().getTotalCount()/1000-1:waybillCountQueryResponseRespR.getData().getTotalCount()/1000;
                for(int i=2;i<pages+2;i++){
                    waybillCountQueryRequest.setPageNo(i);
                    RespR<WaybillCountQueryResponse> waybillCountQueryResponseRespR1 =  noCarInterface.waybillCountQuery(waybillCountQueryRequest);
                    dealMouthAcc(waybillCountQueryResponseRespR1,customerRec);
                }
            }
        }

        log.info("更新取月票啦：NoCarServiceImpl.monthAccQueryUpdate{},msg{}",waybillCountQueryResponseRespR,waybillCountQueryResponseRespR.getMsg());
        return new RespR(true);
    }
    public void dealMouthAcc(RespR<WaybillCountQueryResponse> waybillCountQueryResponseRespR,CustomerRec customerRec){
        String customerName = customerRec.getCustomerName();
        String companyName = customerRec.getCompanyBelongName();
        String buyerName = customerRec.getCompanyName();
        String buyerCode = customerRec.getCompanyReferencenum();
        waybillCountQueryResponseRespR.getData().getResult().forEach(waybillCountQueryModel -> {
            MounthAcc mounthAcc = new MounthAcc();
            mounthAcc.setBuyerName(buyerName);
            mounthAcc.setBuyerTaxpayerCode(buyerCode);
            mounthAcc.setCompanyName(companyName);
            mounthAcc.setCustomerId(customerName);
            mounthAcc.setExTime(DateUtil.tTimeToDate(waybillCountQueryModel.getExTime()));
            mounthAcc.setEnStation(waybillCountQueryModel.getEnStation());
            mounthAcc.setExStation(waybillCountQueryModel.getExStation());
            mounthAcc.setFee(waybillCountQueryModel.getFee());
            mounthAcc.setTradeId(waybillCountQueryModel.getTradeId());
            mounthAcc.setWaybillNum(waybillCountQueryModel.getWaybillNum());
            mounthAccMapper.insert(mounthAcc);
        });
    }
}
