package cn.superdesk.uniorder.service.invoice.customer.state.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerMailTickStatusEnum;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApply;
import cn.superdesk.uniorder.dto.param.invoice.customer.status.OpMailTickStatusFormInnerListItemV2_1;
import cn.superdesk.uniorder.dto.param.invoice.customer.status.OpMailTickStatusFormV2_1;
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.QchjcCustomerStatementEventMultipleStructVo;
import cn.superdesk.uniorder.executor.scheduler.kafka._thirdpart.qchjc.dto.accounting.customer.QchjcCustomerStatementEventSingleStructVo;
import cn.superdesk.uniorder.pattern.state.invoice.customer.invoiceApply.mailTickStatus.context.InvoiceApplyFieldMailTickStatusContext;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyCustomerService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMailTickStatusService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @Description: 简易状态机 星型结构
 * @Author: linjinyu
 * @CreateDate: 10/12/20 4:28 PM
 * @UpdateUser: linjinyu
 * @UpdateDate: 10/12/20 4:28 PM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class InvoiceApplyCustomerFieldMailTickStatusServiceImpl implements InvoiceApplyCustomerFieldMailTickStatusService {

    @Autowired
    private InvoiceApplyCustomerService invoiceApplyService;

    /**************************************** superdesk-uniorder-executor start ****************************************/

    @Autowired
    private QchjcStatementKafkaEventPublisher qchjcStatementEventPublisher;

    /**************************************** superdesk-uniorder-executor   end ****************************************/

    /****************************************** 状态机 公共方法 机内使用 实际流转 重用 start ******************************************/

    // 状态流转为 未邮寄(0, "未邮寄")
    public void opInitByStateMachine(InvoiceApply entity, LoginSysUser loginSysUser) {

        InvoiceApply forUpdate = new InvoiceApply();
        forUpdate.setId(entity.getId());

        // TODO 更新状态逻辑...

        forUpdate.setMailTickStatus(InvoiceApplyCustomerMailTickStatusEnum.未寄票.getKey());

        forUpdate.setMailTickUserId(loginSysUser.getSysUserId());
        forUpdate.setMailTickTime(DateUtil.date());

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

        invoiceApplyService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);
    }

    // 状态流转为 已邮寄(1, "已邮寄")
    public void opCompleteByStateMachine(InvoiceApply entity, LoginSysUser loginSysUser) {

        InvoiceApply forUpdate = new InvoiceApply();
        forUpdate.setId(entity.getId());

        // TODO 更新状态逻辑...

        forUpdate.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.待回款.getKey());
        forUpdate.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
        forUpdate.setInvoiceProgressingTime(DateUtil.date());

        forUpdate.setMailTickStatus(InvoiceApplyCustomerMailTickStatusEnum.已寄票.getKey());
        forUpdate.setMailTickUserId(loginSysUser.getSysUserId());
        forUpdate.setMailTickTime(DateUtil.date());

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

        invoiceApplyService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);
    }

    /**
     * 积分结算_发票管理_寄票登记_op确认寄票(后端已经过滤了线上开票方式)
     * 状态流转为 已邮寄(1, "已邮寄")
     *
     * @param entitys
     * @param form
     * @param loginSysUser
     */
    public void opCompleteByStateMachineV2_1(List<InvoiceApply> entitys, OpMailTickStatusFormV2_1 form, LoginSysUser loginSysUser) {

        /**
         *  key invoiceApplyId
         */
        Map<Long, OpMailTickStatusFormInnerListItemV2_1> shortcut = form.getSubmitList()
                .stream()
                .collect(Collectors.toMap(OpMailTickStatusFormInnerListItemV2_1::getInvoiceApplyId, v -> v, (k, v) -> v));

        DateTime now = DateUtil.date();

        entitys.forEach(entity -> {

            InvoiceApply forUpdate = new InvoiceApply();
            forUpdate.setId(entity.getId());

            OpMailTickStatusFormInnerListItemV2_1 formTmp = shortcut.get(entity.getId());

            if (ObjectUtil.isNotNull(formTmp) && CollUtil.isNotEmpty(formTmp.getInvoiceNumber())) {
                forUpdate.setExpressCompanyId(formTmp.getExpressCompanyId());
                forUpdate.setExpressNo(formTmp.getExpressNo());
            }

            // 如果只是保存一下 那就是这么简单 ^_^
//			if (ObjectUtil.isNotNull(formTmp) && CollUtil.isNotEmpty(formTmp.getInvoiceNumber())) {
//				forUpdate.setInvoiceNumber(AnStringUtils.stringListConvertToString(formTmp.getInvoiceNumber()));
//			}

            // TODO 更新状态逻辑...

            // 当前流水改变状态
            forUpdate.setMailTickStatus(InvoiceApplyCustomerMailTickStatusEnum.已寄票.getKey());
            forUpdate.setMailTickUserId(loginSysUser.getSysUserId());
            forUpdate.setMailTickTime(now);

            // 下个流程状态初始
            forUpdate.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.待回款.getKey());
            forUpdate.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
            forUpdate.setInvoiceProgressingTime(now);

            forUpdate.setUpdateUserId(loginSysUser.getSysUserId());
            forUpdate.setUpdateTime(now);

            invoiceApplyService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);
        });

        /**************************************** 触发事件点 start ****************************************/

        // 触发事件点;集采账单状态推送 TODO
        // 1.来源于“企业商城”的开票申请在**发起开票成功时**：若该对账单的申请状态为“全部申请”**&**所有有效的开票申请的申请状态均为“待回款”时
        // 2.来源于“企业商城”的对账单在**“积分结算-发票管理-【运营寄票】”成功时**：若该对账单的申请状态为“全部申请”**&**所有有效的开票申请的申请状态均为“待回款”时；

        // 拷贝不到
//        List<QchjcCustomerStatementEventSingleStructVo> eventSingleStructVoList = AnBeanUtils.copy(form.getSubmitList(), QchjcCustomerStatementEventSingleStructVo.class);
        List<QchjcCustomerStatementEventSingleStructVo> eventSingleStructVoList = new ArrayList<>();
        form.getSubmitList().forEach(item -> {
            eventSingleStructVoList.add(
                    QchjcCustomerStatementEventSingleStructVo
                            .builder()

                            .invoiceApplyId(item.getInvoiceApplyId())
                            .invoiceApplySn(item.getInvoiceApplySn())
                            .accountingOrderId(item.getAccountingOrderId())
                            .accountingOrderSn(item.getAccountingOrderSn())

                            .build()
            );
        });


        // 触发事件点;集采账单状态推送 #此处只是触点，触点背后会有逻辑判定要不要调用~集采的接口 特此说明# at 20220616
        // 1.来源于“企业商城”的开票申请在**发起开票成功时**：若该对账单的申请状态为“全部申请”**&**所有有效的开票申请的申请状态均为“待回款”时
        // 2.来源于“企业商城”的对账单在**“积分结算-发票管理-【运营寄票】”成功时**：若该对账单的申请状态为“全部申请”**&**所有有效的开票申请的申请状态均为“待回款”时；
        qchjcStatementEventPublisher.customerStatementEventMakeInvoiceStatusSync(
                QchjcCustomerStatementEvent
                        .builder()
                        .msg("积分结算v2.3-发票管理-op寄票登记-op确认寄票(发票种类::不限)(开票方式::不限)")

                        .multipleStructVo(
                                QchjcCustomerStatementEventMultipleStructVo
                                        .builder()
                                        .items(eventSingleStructVoList)
                                        .build()
                        )

                        .loginSysUser(JSONUtil.toJsonStr(loginSysUser))
                        .touchTime(now)

                        .build()
        );

        /**************************************** 触发事件点 start ****************************************/

    }

    /****************************************** 状态机 公共方法 机内使用 实际流转 重用   end ******************************************/


    /****************************************** 状态机 外部使用 类门面 start ******************************************/

    // 状态流转为 未邮寄(0, "未邮寄")
    public void opInit(InvoiceApply entity, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMailTickStatusContext context = new InvoiceApplyFieldMailTickStatusContext(entity, loginSysUser);
        context.opInit();
    }

    // 状态流转为 已邮寄(1, "已邮寄")
    public void opComplete(InvoiceApply entity, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMailTickStatusContext context = new InvoiceApplyFieldMailTickStatusContext(entity, loginSysUser);
        context.opComplete();
    }

    // 状态流转为 已邮寄(1, "已邮寄")
    public void opCompleteV2_1(List<InvoiceApply> entitys, OpMailTickStatusFormV2_1 form, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMailTickStatusContext context = new InvoiceApplyFieldMailTickStatusContext(entitys, form, loginSysUser);
        context.opComplete();
    }

    /****************************************** 状态机 外部使用 类门面   end ******************************************/
}
