package org.springblade.flow.shop.service.impl;

import cn.hutool.core.convert.Convert;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.enums.AppConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.flow.business.constant.AuditCandidate;
import org.springblade.flow.business.service.IFlowService;
import org.springblade.flow.core.constant.ProcessConstant;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.FlowUtil;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.shop.task.callback.ShopInvitationCallback;
import org.springblade.flow.shop.task.callback.ShopInvitationFailCallback;
import org.springblade.flow.shop.task.callback.ShopInvitationSignCallback;
import org.springblade.flow.shop.task.callback.ShopInvitationSuccessCallback;
import org.springblade.flow.shop.entity.InvitationCallbackData;
import org.springblade.flow.shop.entity.ProcessAudit;
import org.springblade.flow.shop.entity.ShopEnum;
import org.springblade.ldt.shop.entity.Audit;
import org.springblade.ldt.shop.entity.Shop;
import org.springblade.ldt.shop.service.IAuditService;
import org.springblade.ldt.shop.service.IShopService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springblade.flow.shop.service.IAuditShopService;

import java.util.Objects;

/**
 * @author: lianghanqiang
 * @description: 商户入驻服务层
 * @since: 9/1/21 -- 3:29 PM
 */
@Service
@AllArgsConstructor
@Slf4j
public class AuditShopService implements IAuditShopService {


	private final IFlowService flowService;
	private IAuditService auditService;
	private IShopService shopService;
	private ShopInvitationFailCallback shopInvitationFailCallback;
	private ShopInvitationSignCallback shopInvitationSignCallback;
	private ShopInvitationSuccessCallback shopInvitationSuccessCallback;


	/**
	 * 商户入驻提交申请
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean startProcess(ProcessAudit processAudit) {
		Audit audit = processAudit.getAudit();
		Shop shop = shopService.getById(audit.getEntityId());
		String businessTable = FlowUtil.getBusinessTable(ProcessConstant.AUDIT_SHOP);
		if (Func.isEmpty(processAudit.getId())) {

			//判断是否由平台审核
			boolean toPlatform = Objects.isNull(shop.getMallId());
			audit.setAuditStatus(toPlatform ? ShopEnum.WAITING_PLATFORM.name() : ShopEnum.WAITING_MALL.name());
			shop.setAuditStatus(toPlatform ? ShopEnum.WAITING_PLATFORM.name() : ShopEnum.WAITING_MALL.name());

			// 保存活动
			audit.setType(AppConstant.PLATFORM.SHOP.name());
			auditService.save(audit);

			// 启动流程
			Kv variables = Kv.create()
				.set("auditId", audit.getId())
				.set("shopId", audit.getEntityId())
				.set("mallTask", TaskUtil.getTaskUserForApp(Convert.toStr(shop.getMallId()), TaskUtil.APP_MALL))
				.set("toPlatform", toPlatform)
				.set("yeepay",AuditCandidate.YEEPAY_PLATFORM.name())
				.set("auditor", AuditCandidate.LDT_PLATFORM.name());

			BladeFlow flow = flowService.startProcessInstanceById(
				audit.getProcessDefinitionId(),
				FlowUtil.getBusinessKey(businessTable,
					String.valueOf(audit.getId())), variables,
				TaskUtil.getTaskUserForApp(Convert.toStr(audit.getEntityId()), TaskUtil.APP_SHOP));

			if (Func.isNotEmpty(flow)) {
				log.debug("流程已启动,流程ID:" + flow.getProcessInstanceId());
				// 返回流程id写入leave
				audit.setProcessInstanceId(flow.getProcessInstanceId());
				auditService.updateById(audit);
				shopService.updateById(shop);
			} else {
				throw new ServiceException("开启流程失败");
			}
		} else {
			auditService.updateById(audit);
			shopService.updateById(shop);
		}
		return true;
	}

	/**
	 * 商户入驻回调通知处理
	 * 根据不同的回调状态调用对应的处理器
	 */
	@Override
	public void invitationCallback(InvitationCallbackData invitationCallbackData) {

		InvitationCallbackData.applicationStatusType applicationStatusType = InvitationCallbackData.applicationStatusType.valueOf(invitationCallbackData.getApplicationStatus());

		switch (applicationStatusType){
			case AGREEMENT_SIGNING:
				shopInvitationSignCallback.handle(invitationCallbackData);
				break;
			case REVIEW_BACK:
				shopInvitationFailCallback.handle(invitationCallbackData);
				break;
			case COMPLETED:
				shopInvitationSuccessCallback.handle(invitationCallbackData);
				break;
		}

	}

}
