package cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.accounting.supplier.biz;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.bizScene.invoice.supplier.InvoiceApplySupplierScene;
import cn.superdesk.uniorder.common.enums.accounting.supplier.AccountingOrderSupplierAccountingStatusEnum;
import cn.superdesk.uniorder.common.enums.common.CommonSourceFromEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierPayOffAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierReceiveInvoiceStatusEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.qchjc.QchjcSupplierPaymentStatusEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.qchjc.QchjcSupplierReceiveInvoiceStatusEnum;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplier;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplier;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.supplier.QchjcSupplierCancelStatementParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.supplier.QchjcSupplierPaymentStatusSyncParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.supplier.QchjcSupplierReceiveInvoiceStatusParam;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.BaseThirdpartQchjcHandleService;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc._constants.ThirdpartQchjcTopicChannelConstants;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.dto.accounting.supplier.QchjcSupplierStatementEvent;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.dto.accounting.supplier.QchjcSupplierStatementEventMultipleStructVo;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.dto.accounting.supplier.QchjcSupplierStatementEventSingleStructVo;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierXGoodsService;
import cn.superdesk.uniorder.service.thirdpart.qchjc.account.QchjcSupplierStatementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2022/5/10 2:43 下午
 * @UpdateUser: linjinyu
 * @UpdateDate: 2022/5/10 2:43 下午
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class QchjcSupplierStatementHandleService extends BaseThirdpartQchjcHandleService {


    @Autowired
    private AccountingUnifiedSupplierService accountingUnifiedSupplierService;

    @Autowired
    private InvoiceApplySupplierService       invoiceApplySupplierService;
    @Autowired
    private InvoiceApplySupplierXGoodsService invoiceApplySupplierXGoodsService;

    @Autowired
    private QchjcSupplierStatementService qchjcSupplierStatementService;


    /**
     * 触发事件点;
     * 1. 来源于“企业商城”的对账单在**“积分结算-发票登记管理-【收票登记】”成功时**：若该对账单所有有效的开票申请的申请状态均为“待付款”时；
     *
     * @param messageKey
     * @param messageBody
     * @param now
     * @return
     */
    public int receiveInvoiceStatusSyncHandle(String messageKey, String messageBody, Date now) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("集采供应商收票状态同步处理开始 messageKey:{} messageBody:{}", messageKey, messageBody);

        QchjcSupplierStatementEvent event = JSONUtil.toBean(messageBody, QchjcSupplierStatementEvent.class);

        LoginSysUser loginSysUser = JSONUtil.toBean(event.getLoginSysUser(), LoginSysUser.class);
        Date         touchTime    = event.getTouchTime();

        String msg = event.getMsg();

        QchjcSupplierStatementEventMultipleStructVo multipleStructVo = event.getMultipleStructVo();

        List<QchjcSupplierStatementEventSingleStructVo> items = multipleStructVo.getItems();

        Integer areYouOk = 0;
        // 目前为 定义项检查
        Integer checkPoint = 3;


        /**************************************** Hey bother! are you ready? start ****************************************/

        // step01 从对账单
        List<String> accountingOrderSns = items
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderSn()))
                .map(QchjcSupplierStatementEventSingleStructVo::getAccountingOrderSn)
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(accountingOrderSns)) {
            return 0;
        }
        if (accountingOrderSns.size() > 1) {
            return 0;
        }

        Long   accountingOrderId = null;
        String accountingOrderSn = accountingOrderSns.get(0);

        AccountingUnifiedSupplier accountingScoreSupplierEntity = accountingUnifiedSupplierService.findByAccountingOrderSn(accountingOrderSn);

        if (ObjectUtil.isNull(accountingScoreSupplierEntity)) {
            return 0;
        }


        accountingOrderSn = accountingScoreSupplierEntity.getAccountingOrderSn();

        // 对账单的申请状态为 全部申请
        if (AccountingOrderSupplierAccountingStatusEnum.已取消.getKey().compareTo(accountingScoreSupplierEntity.getAccountingStatus()) != 0) {
            areYouOk = areYouOk + 1;
        }

        List<InvoiceApplySupplier> invoiceApplySupplierEntitysExistDb = invoiceApplySupplierService.findByAccountingOrderSn(accountingOrderSn);

        /**************************************** 申请状态 start ****************************************/

        List<Integer> invoiceProgressingStatusExistDb = invoiceApplySupplierEntitysExistDb
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getInvoiceStatus()))
                .map(InvoiceApplySupplier::getInvoiceStatus)
                .collect(Collectors.toList());


        /**************************************** 收票状态 start ****************************************/

        List<Integer> receiveInvoiceStatusExistDb = invoiceApplySupplierEntitysExistDb
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getReceiveInvoiceStatus()))
                .map(InvoiceApplySupplier::getReceiveInvoiceStatus)
                .collect(Collectors.toList());

        /**************************************** 发票单 start ****************************************/

        // 所有有效的 开票申请(发票单)
        // 申请状态 均为 待付款       <- 当前
        // |---- 收票状态 均为 已收票
        if (CollUtil.isEmpty(invoiceProgressingStatusExistDb)) {
            return 0;
        } else if (invoiceProgressingStatusExistDb.size() == 1) {

            // 申请状态 唯一的情况
            InvoiceApplySupplierInvoiceProgressingStatusEnum invoiceApplySupplierInvoiceProgressingStatusEnum = InvoiceApplySupplierInvoiceProgressingStatusEnum.get(invoiceProgressingStatusExistDb.get(0));

            // 意思是 唯一情况 待付款
            if (ArrayUtil.contains(
                    InvoiceApplySupplierScene.statusV2_3_Array_InvoiceProgressingSceneOpEventQchjcSupplierStatementReceiveInvoiceStatusSyncStateCheck(),
                    invoiceApplySupplierInvoiceProgressingStatusEnum.getKey())
            ) {
                areYouOk = areYouOk + 1;
            }

        } else if (invoiceProgressingStatusExistDb.size() > 1) {
            // 意思是 不唯一情况
            return 0;
        } else {
        }

        // 所有有效的开票申请的
        // 申请状态 均为 待付款
        // |---- 收票状态 均为 已收票 <- 当前
        if (CollUtil.isEmpty(receiveInvoiceStatusExistDb)) {
            return 0;
        } else if (receiveInvoiceStatusExistDb.size() == 1) {

            // 收票状态 唯一的情况
            InvoiceApplySupplierReceiveInvoiceStatusEnum invoiceApplySupplierReceiveInvoiceStatusEnum = InvoiceApplySupplierReceiveInvoiceStatusEnum.get(receiveInvoiceStatusExistDb.get(0));

            // 意思是 唯一情况 已收票
            if (ArrayUtil.contains(
                    InvoiceApplySupplierScene.statusV2_3_Array_ReceiveInvoiceSceneOpEventQchjcSupplierStatementReceiveInvoiceStatusSyncStateCheck(),
                    invoiceApplySupplierReceiveInvoiceStatusEnum.getKey())
            ) {
                areYouOk = areYouOk + 1;
            }

        } else if (invoiceProgressingStatusExistDb.size() > 1) {
            // 意思是 不唯一情况
            return 0;
        } else {
        }

        /**************************************** Hey bother! are you ready?   end ****************************************/

        Map<String, String> invoiceNumberMap = new HashMap<String, String>();

        invoiceApplySupplierEntitysExistDb.forEach(item -> {
            invoiceNumberMap.put(item.getInvoiceApplySn(), item.getInvoiceNumber());
        });

        tmpLogWithAccountingOrderSn(
                ThirdpartQchjcTopicChannelConstants.TOPIC_EVENT_CHANNEL_QCHJC_SUPPLIER_STATEMENT,
                accountingOrderSn,
                messageKey,
                messageBody,
                DateUtil.format(now, DatePattern.PURE_DATETIME_PATTERN)
        );

//        if (!CommonServiceNoEnum.企业商城_侨城汇.getServiceNo().equals(accountingScoreSupplierEntity.getServiceNo())) {
//            return 0;
//        }

        if (!CommonSourceFromEnum.企业商城_侨城汇.getSourceFromCode().equals(accountingScoreSupplierEntity.getSourceFrom())) {
            return 0;
        }
        log.info("集采供应商对账单收票状态同步判定结果, sn: {}  , areYouOk: {}, checkPoint: {}", accountingOrderSn, areYouOk, checkPoint);
        if (areYouOk.compareTo(checkPoint) >= 0) {

            qchjcSupplierStatementService.receiveInvoiceStatusSync(
                    QchjcSupplierReceiveInvoiceStatusParam
                            .builder()

                            .reconciliationSupplierCode(accountingScoreSupplierEntity.getAccountingOrderSn())

                            .recInvoiceStatusSync(QchjcSupplierReceiveInvoiceStatusEnum.已收票.getStatus())

                            /**************************************** 此步骤没有快递信息 start ****************************************/

//                            .logisticsCompany()
//                            .logisticsNo()
//                            .logisticsCompanyType()

                            /**************************************** 此步骤没有快递信息   end ****************************************/


                            .operatorId(AnStringUtils.getString(loginSysUser.getSysUserId()))
                            .operatorName(loginSysUser.getFullName())
                            .operatorDate(touchTime)

                            .processState(msg)

                            .invoiceNumberMap(invoiceNumberMap)

                            .build()
            );
        }

        return 0;
    }

    /**
     * 触发事件点;
     * 1. 来源于“企业商城”的对账单在**“供应商结算-货款管理-【确认付款】”成功时**：若该对账单的所有有效的开票申请的申请状态均为“已付款”时；（“付款中”状态无需同步。）
     *
     * @param messageKey
     * @param messageBody
     * @param now
     * @return
     */
    public int paymentStatusSyncHandle(String messageKey, String messageBody, Date now) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("集采供应商付款状态同步处理开始 messageKey:{} messageBody:{}", messageKey, messageBody);

        QchjcSupplierStatementEvent event = JSONUtil.toBean(messageBody, QchjcSupplierStatementEvent.class);

        LoginSysUser loginSysUser = JSONUtil.toBean(event.getLoginSysUser(), LoginSysUser.class);
        Date         touchTime    = event.getTouchTime();

        String msg = event.getMsg();

        QchjcSupplierStatementEventMultipleStructVo multipleStructVo = event.getMultipleStructVo();

        List<QchjcSupplierStatementEventSingleStructVo> items = multipleStructVo.getItems();

        Integer areYouOk = 0;
        // 目前为 定义项检查
        Integer checkPoint = 3;


        /**************************************** Hey bother! are you ready? start ****************************************/

        // step01 从对账单
        List<String> accountingOrderSns = items
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderSn()))
                .map(QchjcSupplierStatementEventSingleStructVo::getAccountingOrderSn)
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(accountingOrderSns)) {
            return 0;
        }
        if (accountingOrderSns.size() > 1) {
            return 0;
        }

        Long   accountingOrderId = null;
        String accountingOrderSn = accountingOrderSns.get(0);

        AccountingUnifiedSupplier accountingScoreSupplierEntity = accountingUnifiedSupplierService.findByAccountingOrderSn(accountingOrderSn);

        if (ObjectUtil.isNull(accountingScoreSupplierEntity)) {
            return 0;
        }


        accountingOrderSn = accountingScoreSupplierEntity.getAccountingOrderSn();

        // 对账单的申请状态为 全部申请
        if (AccountingOrderSupplierAccountingStatusEnum.已取消.getKey().compareTo(accountingScoreSupplierEntity.getAccountingStatus()) != 0) {
            areYouOk = areYouOk + 1;
        }

        List<InvoiceApplySupplier> invoiceApplySupplierEntitysExistDb = invoiceApplySupplierService.findByAccountingOrderSn(accountingOrderSn);

        /**************************************** 申请状态 start ****************************************/

        List<Integer> invoiceProgressingStatusExistDb = invoiceApplySupplierEntitysExistDb
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getInvoiceStatus()))
                .map(InvoiceApplySupplier::getInvoiceStatus)
                .collect(Collectors.toList());


        /**************************************** 付款状态 start ****************************************/

        List<Integer> payoffAccountStatusExistDb = invoiceApplySupplierEntitysExistDb
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getPayoffAccountStatus()))
                .map(InvoiceApplySupplier::getPayoffAccountStatus)
                .collect(Collectors.toList());

        /**************************************** 发票单 start ****************************************/

        // 所有有效的 开票申请(发票单)
        // 申请状态 均为 已完成       <- 当前
        // |---- 付款状态 均为 已付款
        if (CollUtil.isEmpty(invoiceProgressingStatusExistDb)) {
            return 0;
        } else if (invoiceProgressingStatusExistDb.size() == 1) {

            // 申请状态 唯一的情况
            InvoiceApplySupplierInvoiceProgressingStatusEnum invoiceApplySupplierInvoiceProgressingStatusEnum = InvoiceApplySupplierInvoiceProgressingStatusEnum.get(invoiceProgressingStatusExistDb.get(0));

            // 意思是 唯一情况 待付款
            if (ArrayUtil.contains(
                    InvoiceApplySupplierScene.statusV2_3_Array_InvoiceProgressingSceneOpEventQchjcSupplierStatementPaymentStatusSyncStateCheck(),
                    invoiceApplySupplierInvoiceProgressingStatusEnum.getKey())
            ) {
                areYouOk = areYouOk + 1;
            }

        } else if (invoiceProgressingStatusExistDb.size() > 1) {
            // 意思是 不唯一情况
            return 0;
        } else {
        }

        // 所有有效的开票申请的
        // 申请状态 均为 已完成
        // |---- 付款状态 均为 已付款 <- 当前
        if (CollUtil.isEmpty(payoffAccountStatusExistDb)) {
            return 0;
        } else if (payoffAccountStatusExistDb.size() == 1) {

            // 收票状态 唯一的情况
            InvoiceApplySupplierPayOffAccountStatusEnum invoiceApplySupplierPayOffAccountStatusEnum = InvoiceApplySupplierPayOffAccountStatusEnum.get(payoffAccountStatusExistDb.get(0));

            // 意思是 唯一情况 已付款
            if (ArrayUtil.contains(
                    InvoiceApplySupplierScene.statusV2_3_Array_ReceiveInvoiceSceneOpEventQchjcSupplierStatementPaymentStatusSyncStateCheck(),
                    invoiceApplySupplierPayOffAccountStatusEnum.getKey())
            ) {
                areYouOk = areYouOk + 1;
            }

        } else if (invoiceProgressingStatusExistDb.size() > 1) {
            // 意思是 不唯一情况
            return 0;
        } else {
        }

        /**************************************** Hey bother! are you ready?   end ****************************************/

        tmpLogWithAccountingOrderSn(
                ThirdpartQchjcTopicChannelConstants.TOPIC_EVENT_CHANNEL_QCHJC_SUPPLIER_STATEMENT,
                accountingOrderSn,
                messageKey,
                messageBody,
                DateUtil.format(now, DatePattern.PURE_DATETIME_PATTERN)
        );

//        if (!CommonServiceNoEnum.企业商城_侨城汇.getServiceNo().equals(accountingScoreSupplierEntity.getServiceNo())) {
//            return 0;
//        }

        if (!CommonSourceFromEnum.企业商城_侨城汇.getSourceFromCode().equals(accountingScoreSupplierEntity.getSourceFrom())) {
            return 0;
        }
        log.info("集采供应商对账单付款状态同步判定结果， sn: {}, areYouOk: {}, checkPoint: {}", accountingOrderSn, areYouOk, checkPoint);
        if (areYouOk.compareTo(checkPoint) >= 0) {

            qchjcSupplierStatementService.paymentStatusSync(
                    QchjcSupplierPaymentStatusSyncParam
                            .builder()

                            .reconciliationSupplierCode(accountingScoreSupplierEntity.getAccountingOrderSn())

                            .paymentStatus(QchjcSupplierPaymentStatusEnum.已付款.getStatus())

                            .operatorId(AnStringUtils.getString(loginSysUser.getSysUserId()))
                            .operatorName(loginSysUser.getFullName())
                            .operatorDate(touchTime)

                            .processState(msg)

                            .build()
            );
        }

        return 0;
    }

    /**
     * 触发事件点;
     * 1. 来源于“企业商城”的对账单在**“供应商结算-对账单-【重新对账】”成功时**；
     *
     * @param messageKey
     * @param messageBody
     * @param now
     * @return
     */
    public int statementCancelSyncHandle(String messageKey, String messageBody, Date now) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("集采供应商对账单取消对账状态同步处理开始 messageKey:{} messageBody:{}", messageKey, messageBody);

        QchjcSupplierStatementEvent event = JSONUtil.toBean(messageBody, QchjcSupplierStatementEvent.class);

        LoginSysUser loginSysUser = JSONUtil.toBean(event.getLoginSysUser(), LoginSysUser.class);
        Date         touchTime    = event.getTouchTime();

        String msg = event.getMsg();

        QchjcSupplierStatementEventSingleStructVo singleStructVo = event.getSingleStructVo();

        Integer areYouOk = 0;
        // 目前为 定义项检查
        Integer checkPoint = 1;


        /**************************************** Hey bother! are you ready? start ****************************************/

        // step01 从对账单
        Long   accountingOrderId = singleStructVo.getAccountingOrderId();
        String accountingOrderSn = null;

        AccountingUnifiedSupplier accountingScoreSupplierEntity = accountingUnifiedSupplierService.findById(accountingOrderId);

        if (ObjectUtil.isNull(accountingScoreSupplierEntity)) {
            return 0;
        }


        accountingOrderSn = accountingScoreSupplierEntity.getAccountingOrderSn();

        // 对账单的申请状态为 全部申请
        if (AccountingOrderSupplierAccountingStatusEnum.已取消.getKey().compareTo(accountingScoreSupplierEntity.getAccountingStatus()) == 0) {
            areYouOk = areYouOk + 1;
        }

        /**************************************** Hey bother! are you ready?   end ****************************************/

        tmpLogWithAccountingOrderSn(
                ThirdpartQchjcTopicChannelConstants.TOPIC_EVENT_CHANNEL_QCHJC_SUPPLIER_STATEMENT,
                accountingOrderSn,
                messageKey,
                messageBody,
                DateUtil.format(now, DatePattern.PURE_DATETIME_PATTERN)
        );

//        if (!CommonServiceNoEnum.企业商城_侨城汇.getServiceNo().equals(accountingScoreSupplierEntity.getServiceNo())) {
//            return 0;
//        }

        if (!CommonSourceFromEnum.企业商城_侨城汇.getSourceFromCode().equals(accountingScoreSupplierEntity.getSourceFrom())) {
            return 0;
        }
        log.info("集采供应商对账单取消对账状态判定结果，sn: {}, areYouOk: {}, checkPoint: {}", accountingOrderSn, areYouOk, checkPoint);
        if (areYouOk.compareTo(checkPoint) >= 0) {

            qchjcSupplierStatementService.statementCancelSync(
                    QchjcSupplierCancelStatementParam
                            .builder()

                            .reconciliationSupplierCode(accountingScoreSupplierEntity.getAccountingOrderSn())

                            .operatorId(AnStringUtils.getString(loginSysUser.getSysUserId()))
                            .operatorName(loginSysUser.getFullName())
                            .operatorDate(touchTime)

                            .processState(msg)

                            .build()
            );
        }

        return 0;
    }
}
