package cn.superdesk.uniorder.service.accounting.score.customer.strategy.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.annotation.AccountingScoreCustomerStrategyType;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomer;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomerXCredit;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomerXCreditExample;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderCredit;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderCreditExample;
import cn.superdesk.uniorder.dao.mapper.accounting.score.customer.AccountingScoreCustomerMapper;
import cn.superdesk.uniorder.dao.mapper.accounting.score.customer.AccountingScoreCustomerXCreditMapper;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderCreditMapper;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.QchjcStatementKafkaEventPublisher;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.dto.accounting.customer.QchjcCustomerStatementEvent;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.dto.accounting.customer.QchjcCustomerStatementEventSingleStructVo;
import cn.superdesk.uniorder.service.accounting.score.customer.strategy.AccountingScoreCustomerStrategy;
import cn.superdesk.uniorder.service.order.base.ScoreOrderService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderCreditService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderGoodsService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyCustomerService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyXGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xc
 * @description 集采 - 类型来源取值自CommonSourceFromEnum
 * @date 2022/5/20 16:01
 */
@Component
@Slf4j
@AccountingScoreCustomerStrategyType("qyscjc-mall-qch")
public class QchjcAccountingScoreCustomerStrategy implements AccountingScoreCustomerStrategy {

    @Autowired
    private AccountingScoreCustomerMapper accountingScoreCustomerMapper;
    @Autowired
    private AccountingScoreCustomerXCreditMapper accountingScoreCustomerXCreditMapper;
    @Autowired
    private UnifiedOrderCreditMapper unifiedOrderCreditMapper;
    @Autowired
    private UnifiedOrderCreditService unifiedOrderCreditService;
    @Autowired
    private UnifiedOrderGoodsService unifiedOrderGoodsService;
    @Autowired
    private UnifiedOrderService unifiedOrderService;
    @Autowired
    private ScoreOrderService scoreOrderService;
    @Autowired
    private InvoiceApplyCustomerService invoiceApplyCustomerService;
    @Autowired
    private InvoiceApplyXGoodsService invoiceApplyXGoodsService;

    /**************************************** superdesk-uniorder-executor start ****************************************/
    @Autowired
    private QchjcStatementKafkaEventPublisher qchjcStatementEventPublisher;

    @Override
    public int opCancelAccounting(AccountingScoreCustomer existDB, Integer accountingStatus, LoginSysUser loginSysUser) {

        /**
         * 20220609 沿用老的逻辑，不做修改
         *
         * 将对账单中的流水数据释放回未对账流水中，流水的对账状态变更为“未对账”
         */
        Long accountingOrderId = existDB.getId();
        // 查出 对账单 与 积分流水 关联
        AccountingScoreCustomerXCreditExample xExample = new AccountingScoreCustomerXCreditExample();
        xExample.createCriteria()
                .andAccountingOrderSnEqualTo(existDB.getAccountingOrderSn());

        List<AccountingScoreCustomerXCredit> x = accountingScoreCustomerXCreditMapper.selectByExample(xExample);

        log.info("查出 对账单 与 积分流水 关联,\n {}", AnJsonUtils.toPrettyJson(x));

        List<Long> creditIds = x.stream()
                .map(AccountingScoreCustomerXCredit::getUnifiedOrderCreditId)
                .collect(Collectors.toList());

        List<Long> xIds = x.stream()
                .map(AccountingScoreCustomerXCredit::getId)
                .collect(Collectors.toList());


//        if(CommonSourceFromEnum.结算中心)

        /**************************************** v2.3 逻辑 mark by linjinyu at 20220518 start ****************************************/

        //集采重新对账 流水改为不对账
        Integer setCreditAccountingStateCustomer = CommonAccountingStateEnum.不对账.getKey();

        /**************************************** v2.3 逻辑 mark by linjinyu at 20220518   end ****************************************/


        if (CollUtil.isNotEmpty(creditIds)) {

            // 还原积分流水 对账状态
            UnifiedOrderCredit updateSample = new UnifiedOrderCredit();
            // |---- 客户对账:1-已对账;2-未对账
            updateSample.setAccountingStateCustomer(setCreditAccountingStateCustomer);

            UnifiedOrderCreditExample updateExample = new UnifiedOrderCreditExample();
            updateExample.createCriteria()
                    .andIdIn(creditIds);
            unifiedOrderCreditMapper.updateByExampleSelective(updateSample, updateExample);
        }


        // 屏蔽 为了已取消 对账单能 查看详情
        // 删除 x
        // AccountingScoreCustomerXCreditExample xDeleteExample = new AccountingScoreCustomerXCreditExample();
        // xDeleteExample.createCriteria()
        // 		.andIdIn(xIds);
        // accountingScoreCustomerXCreditMapper.deleteByExample(xDeleteExample);


        // 更新 对账单
        AccountingScoreCustomer forUpdate = new AccountingScoreCustomer();

        forUpdate.setId(accountingOrderId);
        forUpdate.setAccountingStatus(accountingStatus);// 对账单状态:0-未确认;1-已确认;-1-已取消;2-是什么鬼;

        forUpdate.setUpdateTime(DateUtil.date());
        forUpdate.setUpdateUserId(loginSysUser.getSysUserId());

        accountingScoreCustomerMapper.updateByPrimaryKeySelective(forUpdate);


        DateTime now = DateUtil.date();

        // 触发事件点;集采账单状态推送 TODO
        // 1. 来源于“企业商城”的对账单在**“积分结算-对账单-【重新对账】”成功时**；
        qchjcStatementEventPublisher.customerStatementEventStatementCancelSync(
                QchjcCustomerStatementEvent
                        .builder()
                        .msg("积分结算v2.3-对账单-op重新对账")

                        .singleStructVo(
                                QchjcCustomerStatementEventSingleStructVo
                                        .builder()
                                        .accountingOrderId(existDB.getId())
                                        .accountingOrderSn(existDB.getAccountingOrderSn())

                                        .invoiceApplyId(0L)
                                        .invoiceApplySn("")
                                        .build()
                        )
                        .loginSysUser(JSONUtil.toJsonStr(loginSysUser))
                        .touchTime(now)
                        .build()
        );

        return 1;
    }
}
