package cn.superdesk.uniorder.service.invoice.supplier.impl;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierMakeInvoiceStatusEnum;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplier;
import cn.superdesk.uniorder.dto.param.invoice.supplier.status.InvoiceApplySupplierOpCommonDimAccountingOrderForm;
import cn.superdesk.uniorder.pattern.state.invoice.supplier.invoiceApplySupplier.makeInvoiceStatus.context.InvoiceApplySupplierFieldMakeInvoiceStatusContext;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierFieldMakeInvoiceStatusService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierXGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
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 InvoiceApplySupplierFieldMakeInvoiceStatusServiceImpl implements InvoiceApplySupplierFieldMakeInvoiceStatusService {

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

	@Autowired
	private AccountingUnifiedSupplierService accountingUnifiedSupplierService;

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

	// 状态流转为 未开票(0, "未开票")
	public void opInitByStateMachine(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {

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

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

		forUpdate.setMakeInvoiceStatus(InvoiceApplySupplierMakeInvoiceStatusEnum.未开票.getKey());
		forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
		forUpdate.setMakeInvoiceTime(DateUtil.date());

		invoiceApplySupplierService.updateInvoiceApplySupplierByPrimaryKeySelective(forUpdate);
	}

	// 状态流转为 已开票(1, "已开票")
	public void opCompleteByStateMachine(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {

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

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

		forUpdate.setMakeInvoiceStatus(InvoiceApplySupplierMakeInvoiceStatusEnum.已开票.getKey());
		forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
		forUpdate.setMakeInvoiceTime(DateUtil.date());

		invoiceApplySupplierService.updateInvoiceApplySupplierByPrimaryKeySelective(forUpdate);
	}

	// 状态流转为 已开票(1, "已开票")
	public void opCompleteByStateMachine(List<InvoiceApplySupplier> entitys, InvoiceApplySupplierOpCommonDimAccountingOrderForm form, LoginSysUser loginSysUser) {

		entitys.forEach(entity -> {

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

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

			forUpdate.setMakeInvoiceStatus(InvoiceApplySupplierMakeInvoiceStatusEnum.已开票.getKey());
			forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
			forUpdate.setMakeInvoiceTime(DateUtil.date());

			// 进入下一个流程
			forUpdate.setInvoiceStatus(InvoiceApplySupplierInvoiceProgressingStatusEnum.待收票.getKey());

			invoiceApplySupplierService.updateInvoiceApplySupplierByPrimaryKeySelective(forUpdate);
		});

		List<Long> processInvoiceApplyIds    = entitys.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getId())).map(o -> o.getId()).collect(Collectors.toList());
		List<Long> processAccountingOrderIds = invoiceApplySupplierXGoodsService.getAffectedAccountingOrderIdsByInvoiceApplyIds(processInvoiceApplyIds);

		processAccountingOrderIds.forEach(accountingOrderId -> {
			accountingUnifiedSupplierService.updateFieldInvoiceStatus(accountingOrderId, InvoiceApplySupplierInvoiceProgressingStatusEnum.待收票, loginSysUser);
		});
	}

	// 状态流转为 已撤消(2, "已撤消")
	public void opBecomeInvalidByStateMachine(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {

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

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

		forUpdate.setMakeInvoiceStatus(InvoiceApplySupplierMakeInvoiceStatusEnum.已撤消.getKey());
		forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
		forUpdate.setMakeInvoiceTime(DateUtil.date());

		invoiceApplySupplierService.updateInvoiceApplySupplierByPrimaryKeySelective(forUpdate);
	}

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


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

	// 状态流转为 未开票(0, "未开票")
	public void opInit(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {
		InvoiceApplySupplierFieldMakeInvoiceStatusContext context = new InvoiceApplySupplierFieldMakeInvoiceStatusContext(entity, loginSysUser);
		context.opInit();
	}

	// 状态流转为 已开票(1, "已开票")
	public void opComplete(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {
		InvoiceApplySupplierFieldMakeInvoiceStatusContext context = new InvoiceApplySupplierFieldMakeInvoiceStatusContext(entity, loginSysUser);
		context.opComplete();
	}

	// 状态流转为 已开票(1, "已开票")
	public void opComplete(List<InvoiceApplySupplier> entitys, InvoiceApplySupplierOpCommonDimAccountingOrderForm form, LoginSysUser loginSysUser) {
		InvoiceApplySupplierFieldMakeInvoiceStatusContext context = new InvoiceApplySupplierFieldMakeInvoiceStatusContext(entitys, form, loginSysUser);
		context.opComplete();
	}

	// 状态流转为 已撤消(2, "已撤消")
	public void opBecomeInvalid(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {
		InvoiceApplySupplierFieldMakeInvoiceStatusContext context = new InvoiceApplySupplierFieldMakeInvoiceStatusContext(entity, loginSysUser);
		context.opBecomeInvalid();
	}

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