package com.clx.performance.service.impl.broker;

import com.clx.order.enums.InvoicingCompanyEnum;
import com.clx.order.enums.QuotationEnum;
import com.clx.order.feign.InvoicingCompanyFeign;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.pc.owner.OwnerQuotationDetailVO;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.OrderGoodsDao;
import com.clx.performance.dao.settle.SettlementDriverDao;
import com.clx.performance.dao.settle.SettlementDriverDetailDao;
import com.clx.performance.dao.settle.SettlementOrderChildRiskDao;
import com.clx.performance.dao.settle.SettlementOwnerDetailDao;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.settle.SettlementDriverDetailEnum;
import com.clx.performance.enums.settle.SettlementOrderChildRiskEnum;
import com.clx.performance.enums.settle.SettlementOwnerDetailEnum;
import com.clx.performance.extranal.order.QuotationService;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.settle.SettlementDriver;
import com.clx.performance.model.settle.SettlementDriverDetail;
import com.clx.performance.model.settle.SettlementOrderChildRisk;
import com.clx.performance.model.settle.SettlementOwnerDetail;
import com.clx.performance.service.broker.OrderChildBrokerMqHandlerService;
import com.clx.performance.service.broker.OrderChildBrokerMqService;
import com.clx.performance.service.broker.OrderChildBrokerService;
import com.clx.performance.vo.mq.broker.BrokerOrderChildDriverPayMqParam;
import com.clx.performance.service.settle.SettlementPostService;
import com.clx.performance.vo.mq.broker.BrokerOrderChildDriverPayMqParam;
import com.clx.performance.service.settle.SettlementPostService;
import com.clx.performance.vo.mq.broker.BrokerOrderChildSyncMqParam;
import com.clx.performance.vo.mq.broker.BrokerOrderChildUpdateMqParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@Service
public class OrderChildBrokerMqHandlerServiceImpl implements OrderChildBrokerMqHandlerService {

    private static final Integer DELAY_TIME = 20;
    @Autowired
    private OrderGoodsDao orderGoodsDao;
    @Autowired
    private OrderChildDao orderChildDao;
    @Autowired
    private SettlementOwnerDetailDao settlementOwnerDetailDao;
    @Autowired
    private SettlementDriverDetailDao settlementDriverDetailDao;
    @Autowired
    private SettlementDriverDao settlementDriverDao;
    @Autowired
    private OrderChildBrokerService orderChildBrokerService;
    @Autowired
    private OrderChildBrokerMqService orderChildBrokerMqService;
    @Autowired
    private SettlementOrderChildRiskDao settlementOrderChildRiskDao;

    @Autowired
    private SettlementPostService settlementPostService;

    @Autowired
    private QuotationService quotationService;

    @Autowired
    private InvoicingCompanyFeign invoicingCompanyFeign;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void orderChildSync(BrokerOrderChildSyncMqParam mq) {

        try{
            doOrderChildSync(mq);
            // 同步-无车承运成功后，更新开票标识为普通单
            updateInvoiceTypeByChildNo(mq.getChildNo());

        }catch (Exception e){
            log.info("无车承运-运单同步 失败，msg:{}", ExceptionUtils.getStackTrace(e));

            OrderChild orderChild = orderChildDao
                    .getByChildNo(mq.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
            SettlementOwnerDetail settlementOwnerDetail = settlementOwnerDetailDao
                    .getByChildNo(orderChild.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

            SettlementOrderChildRisk settlementOrderChildRisk = new SettlementOrderChildRisk();
            settlementOrderChildRisk.setChildNo(orderChild.getChildNo());
            settlementOrderChildRisk.setTruckNo(orderChild.getTruckNo());
            settlementOrderChildRisk.setDriverName(orderChild.getDriverName());
            settlementOrderChildRisk.setDriverMobile(orderChild.getDriverMobile());
            settlementOrderChildRisk.setGoodsName(orderChild.getGoodsName());
            settlementOrderChildRisk.setInvoiceType(settlementOwnerDetail.getInvoiceType());
            // 如果有发票配置，则更新
            if (Objects.nonNull(settlementOwnerDetail.getInvoiceConfigType())) {
                settlementOrderChildRisk.setInvoiceConfigType(settlementOwnerDetail.getInvoiceConfigType());
            }
            settlementOrderChildRisk.setPoundAuditTime(settlementOwnerDetail.getPoundAuditTime());
            settlementOrderChildRisk.setRiskType(SettlementOrderChildRiskEnum.RiskType.SETTLE_FAIL.getCode());
            settlementOrderChildRisk.setRiskRemark("同步无车承运异常");
            // 若开票配置为是
            if (this.invoiceConfigType(orderChild.getOrderNo())) {
                settlementOrderChildRiskDao.saveEntity(settlementOrderChildRisk);
                log.info("当前运单的关联的订单开票配置为是，保存对应封控的信息入库");
            }
            settlementPostService.riskAdd(settlementOrderChildRisk.getId());
        }
    }
    public void doOrderChildSync(BrokerOrderChildSyncMqParam mq){
        String childNo = mq.getChildNo();

        OrderChild orderChild = orderChildDao
                .getByChildNo(childNo).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        OrderGoods orderGoods = orderGoodsDao
                .getByOrderGoodsNo(orderChild.getOrderGoodsNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

        SettlementOwnerDetail settlementOwnerDetail = settlementOwnerDetailDao
                .getByChildNo(orderChild.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        SettlementDriverDetail settlementDriverDetail = settlementDriverDetailDao
                .getByChildNo(orderChild.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

        // 更新状态
        settlementOwnerDetail.setInvoiceTypeStatus(SettlementOwnerDetailEnum.InvoiceTypeStatus.PROCESSING.getCode());
        settlementOwnerDetailDao.updateInvoiceTypeStatus(settlementOwnerDetail);

        try{
            // 同步broker
            orderChildBrokerService.orderChildSync(orderChild, orderGoods, settlementOwnerDetail, settlementDriverDetail);
        } catch (Exception e) {
            log.info("同步无车承运失败, child:{}, msg:{}", orderChild.getChildNo(), ExceptionUtils.getStackTrace(e));
        }

    }
    @Override
    public void orderChildUpdate(BrokerOrderChildUpdateMqParam mq) {
        String childNo = mq.getChildNo();

        OrderChild orderChild = orderChildDao
                .getByChildNo(childNo).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        OrderGoods orderGoods = orderGoodsDao
                .getByOrderGoodsNo(orderChild.getOrderGoodsNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

        SettlementOwnerDetail settlementOwnerDetail = settlementOwnerDetailDao
                .getByChildNo(orderChild.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        SettlementDriverDetail settlementDriverDetail = settlementDriverDetailDao
                .getByChildNo(orderChild.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        SettlementDriver settlementDriver = settlementDriverDao
                .getByChildNo(orderChild.getChildNo()).orNull();

        if (Objects.equals(settlementOwnerDetail.getReportFlag(), com.clx.order.enums.OrderEnum.ReportFlag.NO.getCode())){
            return;
        }

        // 延迟推送
        if (settlementOwnerDetail.getCreateTime().isAfter(LocalDateTime.now().minusSeconds(DELAY_TIME))){
            // 发送mq (运单更新)
            orderChildBrokerMqService.orderChildUpdate(childNo);
            return;
        }

        try{
            // 更新broker
            orderChildBrokerService.orderChildUpdate(orderChild, orderGoods, settlementOwnerDetail,
                    settlementDriverDetail, settlementDriver);
        } catch (Exception e) {
            log.info("更新无车承运失败, child:{}, msg:{}", orderChild.getChildNo(), ExceptionUtils.getStackTrace(e));
        }

    }

    @Override
    public void orderChildDriverPay(BrokerOrderChildDriverPayMqParam mq) {
        SettlementDriverDetail settlementDriverDetail = settlementDriverDetailDao
                .getByChildNo(mq.getChildNo()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

        settlementDriverDetail.setPayAcceptStatus(SettlementDriverDetailEnum.PayAcceptStatus.ACCEPTING.getCode());
        settlementDriverDetailDao.updatePayAcceptStatus(settlementDriverDetail);

        // 司机支付
        orderChildBrokerService.orderChildDriverPay(settlementDriverDetail);

    }

    /**
     * 开票配置为是
     *
     * @param orderNo
     * @return
     */
    public boolean invoiceConfigType(String orderNo) {
        // 调用开票配置接口
        Integer invoiceConfigType = invoicingCompanyFeign.getInvoicingConfigTypeByOrderNo(orderNo).getData();
        log.info("notInvoiceConfigType invoiceConfigType:{}", invoiceConfigType);
        // 若开票配置为是
        return Objects.nonNull(invoiceConfigType) && Objects.equals(invoiceConfigType,
                QuotationEnum.InvoicingConfigType.YES.getCode());
    }

    /**
     * 更新当前运单号，更新开票标识为普通单
     */
    public void updateInvoiceTypeByChildNo(String childNo) {
        // 获取货主详情
        SettlementOwnerDetail settlementOwnerDetail = settlementOwnerDetailDao
                .getByChildNo(childNo).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        // 获取车主详情
        SettlementDriverDetail settlementDriverDetail = settlementDriverDetailDao
                .getByChildNo(childNo).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        // 开票配置为否时，更新开票标识为普通单
        if (!this.invoiceConfigType(settlementOwnerDetail.getOrderNo())) {
            // 货主更新开票标识
            settlementOwnerDetail.setInvoiceType(InvoicingCompanyEnum.RiskProcessType.AUTO.getCode());
            settlementOwnerDetailDao.updateEntityByKey(settlementOwnerDetail);
            // 车主更新开票标识
            settlementDriverDetail.setInvoiceType(InvoicingCompanyEnum.RiskProcessType.AUTO.getCode());
            settlementDriverDetailDao.updateEntityByKey(settlementDriverDetail);
        }
    }

}
