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

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.invoice.common.InvoiceTypeMoudelXModeEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerMakeInvoiceStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceMakeStatusEnum;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApply;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.common.singleBilling.SzhtxxInvoiceFptxxOpSingleBillingForm;
import cn.superdesk.uniorder.pattern.state.invoice.customer.invoiceApply.makeInvoiceStatus.context.InvoiceApplyFieldMakeInvoiceStatusContext;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderCreditService;
import cn.superdesk.uniorder.service.invoice.customer.*;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingOffLineService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMakeInvoiceStatusService;
import cn.superdesk.uniorder.service.sys.notify.SysNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @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 InvoiceApplyCustomerFieldMakeInvoiceStatusServiceImpl implements InvoiceApplyCustomerFieldMakeInvoiceStatusService {

    @Autowired
    private InvoiceApplyCustomerService            invoiceApplyCustomerService;
    @Autowired
    private InvoiceApplyCustomerExportExcelService invoiceApplyCustomerExportExcelService;

    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingOffLineService                 invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingOffLineService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService      invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService;

    @Autowired
    private InvoiceApplyXGoodsService invoiceApplyXGoodsService;
    @Autowired
    private UnifiedOrderCreditService unifiedOrderCreditService;

    @Autowired
    private SysNotifyService sysNotifyService;


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

    // 状态流转为 待开票(0, "待开票")
    public SysNotify opInitByStateMachine(InvoiceApply entity, LoginSysUser loginSysUser) {

        DateTime now = DateUtil.date();

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

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

        forUpdate.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.待开票.getKey());
        forUpdate.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
        forUpdate.setInvoiceProgressingTime(now);

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

        invoiceApplyCustomerService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);

        return sysNotifyService.receiveInvoiceApplyCustomerFieldMakeInvoiceStatusSuccess(loginSysUser);
    }

    // 状态流转为 已作废(2, "已作废")
    public SysNotify opBecomeInvalidByStateMachine(InvoiceApply entity, LoginSysUser loginSysUser) {

        DateTime now = DateUtil.date();

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

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

        forUpdate.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.已作废.getKey());
        forUpdate.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
        forUpdate.setInvoiceProgressingTime(now);

//        forUpdate.setMakeInvoiceStatus(InvoiceApplyCustomerMakeInvoiceStatusEnum.重新开票.getKey());
        forUpdate.setInvoiceNumber(null);
        forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
        forUpdate.setMakeInvoiceTime(now);
        forUpdate.setInvoiceNumber(null);

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

        invoiceApplyCustomerService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);

        return sysNotifyService.receiveInvoiceApplyCustomerFieldMakeInvoiceStatusSuccess(loginSysUser);
    }

    // 状态流转为 开票中(10, "开票中")
    public SysNotify opOngoingByStateMachine(SzhtxxInvoiceFptxxOpSingleBillingForm form, InvoiceApply entity, LoginSysUser loginSysUser) {

        switch (InvoiceTypeMoudelXModeEnum.get(entity.getInvoiceMode())) {
            case 线下开票:
                return invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingOffLineService
                        .submitAndRecord(
                                entity,
                                loginSysUser
                        );
            case 深圳航信电子发票:
                return invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService
                        .submitAndRecord(
                                form,
                                entity,
                                loginSysUser
                        );
            case 深圳航信纸质发票:
                return invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService
                        .submitAndRecord(
                                form,
                                entity,
                                loginSysUser
                        );
            default:
                return SysNotify.builder()
                        .title("0001")
                        .content("该发票种类无此开票方式")
                        .build();
        }

    }


    // 状态流转为 已开票(11, "已开票")
    public SysNotify opCompleteByStateMachine(InvoiceApply entity, LoginSysUser loginSysUser) {


        DateTime now = DateUtil.date();

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

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

        forUpdate.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.待领票.getKey());
        forUpdate.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
        forUpdate.setInvoiceProgressingTime(now);

        forUpdate.setMakeInvoiceStatus(InvoiceApplyCustomerMakeInvoiceStatusEnum.已开票.getKey());
        forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
        forUpdate.setMakeInvoiceTime(now);

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

        invoiceApplyCustomerService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);

        // 从 op发起开票 -> 线下开票
        List<Long> processUnifiedOrderCreditIds = invoiceApplyXGoodsService.findCreditSetByInvoicApplyId(entity.getId());
        unifiedOrderCreditService.updateFieldInvoiceMakeStatusByUnifiedOrderCreditIds(processUnifiedOrderCreditIds, UnifiedOrderCreditInvoiceMakeStatusEnum.已开票);

        return sysNotifyService.receiveInvoiceApplyCustomerFieldMakeInvoiceStatusSuccess(loginSysUser);


    }

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


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

    // 状态流转为 待开票(0, "待开票")
    public SysNotify opInit(InvoiceApply entity, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMakeInvoiceStatusContext context = new InvoiceApplyFieldMakeInvoiceStatusContext(entity, loginSysUser);
        return context.opInit();
    }

    // 状态流转为 已作废(2, "已作废")
    public SysNotify opBecomeInvalid(InvoiceApply entity, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMakeInvoiceStatusContext context = new InvoiceApplyFieldMakeInvoiceStatusContext(entity, loginSysUser);
        return context.opBecomeInvalid();
    }


    // 状态流转为 开票中(10, "开票中")
    public SysNotify opOngoing(SzhtxxInvoiceFptxxOpSingleBillingForm form, InvoiceApply entity, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMakeInvoiceStatusContext context = new InvoiceApplyFieldMakeInvoiceStatusContext(form, entity, loginSysUser);
        return context.opOngoing();
    }


    // 状态流转为 已开票(11, "已开票")
    public SysNotify opComplete(InvoiceApply entity, LoginSysUser loginSysUser) {
        InvoiceApplyFieldMakeInvoiceStatusContext context = new InvoiceApplyFieldMakeInvoiceStatusContext(entity, loginSysUser);
        return context.opComplete();
    }

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