package org.springblade.flow.shop.task.callback;

import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.FlowCache;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.sms.model.SmsData;
import org.springblade.flow.business.constant.AuditCandidate;
import org.springblade.flow.business.service.FlowBusinessService;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.shop.entity.InvitationCallbackData;
import org.springblade.flow.shop.entity.InvitationCallbackVO;
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.springblade.modules.resource.utils.SmsUtil;
import org.springblade.wx.config.ConfigForShop;
import org.springblade.wx.constant.MessageTemplate;
import org.springblade.wx.constant.MiniProgramType;
import org.springblade.wx.service.WeChatService;
import org.springblade.wx.utils.UrlTransform;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author: lianghanqiang
 * @description: 商户入驻待签约
 * @since: 9/6/21 -- 6:49 PM
 */
@Component
@AllArgsConstructor
public class ShopInvitationSignCallback implements ShopInvitationCallback {

	private  FlowBusinessService flowBusinessService;
	private  IShopService shopService;
	private  IAuditService auditService;
	private WeChatService weChatService;
	private ConfigForShop configForShop;

	@Override
	@Transactional
	public  void handle(InvitationCallbackData invitationCallbackData) {

		//获取缓存的流程信息
		InvitationCallbackVO invitationCallbackVO = FlowCache.getAudit(invitationCallbackData.getRequestNo());
		Assert.notNull(invitationCallbackVO,() -> {throw new ServiceException("商户入驻回调异常：找不到对应的流程信息");});



		//获取对应的业务表对象
		Shop shop = invitationCallbackVO.getShop();
		Audit audit = invitationCallbackVO.getAudit();

		if(Objects.equals(audit.getAuditStatus(),ShopEnum.WAITING_SIGN.name())){
			return;
		}


		shop.setMerchantNo(invitationCallbackData.getMerchantNo());


		//通知商户签约
		notifyToSign(invitationCallbackData,shop);

		//处理流程流传
		BladeFlow bladeFlow = new BladeFlow();
		bladeFlow.setProcessInstanceId(audit.getProcessInstanceId());
		bladeFlow.setAssignee(AuditCandidate.YEEPAY_PLATFORM.name());
//		bladeFlow.getVariables().put("requestNo",invitationCallbackData.getRequestNo());
		List<BladeFlow> records = flowBusinessService.selectTodoPage(new Page<BladeFlow>(), bladeFlow).getRecords();
		BladeFlow task= records.get(0);
		Assert.notNull(task,() -> {throw new ServiceException("商户入驻回调异常：找不到对应的流程任务");});

		task.setComment(invitationCallbackData.getAuditOpinion());
		task.setPass(Boolean.TRUE);
		task.getVariables().put("approve",Boolean.TRUE);
		task.getVariables().put("signUrl",invitationCallbackData.getAgreementSignUrl());
		task.getVariables().put("requestNo",invitationCallbackData.getRequestNo());
		task.getVariables().put("isMicro",Boolean.FALSE);
		Assert.isTrue(flowBusinessService.completeTask(task),()->{ throw new ServiceException(" 商户入驻回调异常： 入驻申请签约处理异常！ "); });



		//修改审核状态
		audit.setAuditStatus(ShopEnum.WAITING_SIGN.name());
		shop.setAuditStatus(ShopEnum.WAITING_SIGN.name());

		Assert.isTrue(auditService.saveOrUpdate(audit),()->{ throw new ServiceException(" 商户入驻回调异常： 入驻申请签约处理异常！ "); });
		Assert.isTrue(shopService.saveOrUpdate(shop),()->{ throw new ServiceException(" 商户入驻回调异常： 入驻申请签约处理异常！ "); });
	}

	/**
	 *	通知相应的商户进行签约
	 * */
	private void notifyToSign(InvitationCallbackData invitationCallbackData,Shop shop){

		//签约地址 业务域名拦截处理
		String signUrl = UrlTransform.cheakUrl(invitationCallbackData.getAgreementSignUrl());

		String phoneNum = shop.getPersonTel();
		String openId = shop.getOpenId();

		sendMessageTemplate(signUrl,openId);
		sendSms(signUrl,phoneNum);
	}


	/**
	 * 	发送模板消息通知商户签约
	 * */
	private void sendMessageTemplate(String signUrl, String openId){
		/*"ofVsB4-Gf4f45altMf0FbMbSCZmU"*/
		JSONObject data = JSON.parseObject(String.format(MessageTemplate.INVITATION_SIGN.getContentString(), "商户签约","请进入小程序完成签约！"));
		//通知用户签约
		weChatService.sendTemplateMessage(openId,
			MessageTemplate.INVITATION_SIGN,
			data,
			String.format(configForShop.getSignPage(),signUrl),
			MiniProgramType.SHOP);
	}

	/**
	 * 	发送短信邀请用户签约
	 * */
	private void sendSms(String signUrl, String phoneNum){
		Map<String,String> params = new HashMap<>();
		params.put("signUrl",signUrl);
		SmsData smsData = new SmsData(params);
		SmsUtil.getBuilder().template().sendSingle(smsData,phoneNum);
	}
}
