package com.cpop.jambox.framework.tasks;

import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SpringUtils;
import com.cpop.jambox.business.bo.LearnNowPayLaterPlanBo;
import com.cpop.jambox.business.entity.CardTemplate;
import com.cpop.jambox.business.entity.CardTemplateExtend;
import com.cpop.jambox.business.service.CardTemplateExtendService;
import com.cpop.pay.framewok.config.wxPay.WxPayConfiguration;
import com.cpop.pay.framewok.handler.wxPay.WxPayHandler;
import com.cpop.system.business.entity.WxPayScore;
import com.cpop.system.business.entity.WxPayScoreDetail;
import com.cpop.system.business.service.WxPayScoreDetailService;
import com.cpop.system.business.service.WxPayScoreService;
import com.github.binarywang.wxpay.bean.payscore.PayScorePlanDetailRequest;
import com.github.binarywang.wxpay.bean.payscore.WxPartnerPayScoreSignPlanRequest;
import com.github.binarywang.wxpay.bean.payscore.WxPartnerPayScoreSignPlanResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.PartnerPayScoreSignPlanService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.row.Row;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

import static com.cpop.system.business.entity.table.WxPayScoreTableDef.WX_PAY_SCORE;

/**
 * @author DB
 * @version 1.0.0
 * @since 2024-01-17 18:18
 */
@Component
@Slf4j
public class LearnNowPayLaterTask {

    @Autowired
    private WxPayHandler wxPayHandler;

    @Autowired
    private WxPayConfiguration wxPayConfiguration;

    /**
     * 异步创建先学后付计划
     * @author DB
     * @since 2024/1/17
     * @param cardTemplate 课卡模板
     * @param payType 支付类型
     */
    @Async("customAsyncThreadPool")
    @Transactional(rollbackFor = Exception.class)
    public void asyncCreateLearnNowPayLaterPlan(CardTemplate cardTemplate, LearnNowPayLaterPlanBo bo, Integer payType) {
        String subMchId = wxPayHandler.getSubMchId(cardTemplate.getBrandId(), cardTemplate.getStoreId());
        //录入计划与详情
        WxPayScore wxPayScore = BeanUtils.mapToClass(bo, WxPayScore.class);
        wxPayScore.setSignAccount(subMchId).setClassHour(bo.getClassHour());
        WxPayScoreService wxPayScoreService = SpringUtils.getBean(WxPayScoreService.class);
        wxPayScoreService.save(wxPayScore);
        //创建计划
        WxPayService wxPayService = wxPayHandler.getWxPayService(null, subMchId);
        PartnerPayScoreSignPlanService partnerPayScoreSignPlanService = wxPayService.getPartnerPayScoreSignPlanService();
        WxPartnerPayScoreSignPlanRequest planRequest = BeanUtils.mapToClass(bo,WxPartnerPayScoreSignPlanRequest.class);
        List<PayScorePlanDetailRequest> payScorePlanDetailRequests = BeanUtils.mapToList(bo.getPlanDetailList(), PayScorePlanDetailRequest.class);
        planRequest.setAppid(wxPayConfiguration.getProperties().getServiceAppId());
        planRequest.setSubMchid(subMchId);
        planRequest.setPlanDetailList(payScorePlanDetailRequests);
        planRequest.setMerchantPlanNo(wxPayScore.getId());
        WxPartnerPayScoreSignPlanResult result;
        CardTemplateExtendService cardTemplateExtendService = SpringUtils.getBean(CardTemplateExtendService.class);
        //设置商户侧计划
        try {
            result = partnerPayScoreSignPlanService.createPlans(planRequest);
        } catch (WxPayException e) {
            //删除计划开通
            try {
                //查询旧表
                DataSourceKey.use("jambox");
                Row oldTemplate = DbChain.table("t_card_template")
                        .select("template_id as oldTemplateId")
                        .select("pay_type as payTypes")
                        .from("t_card_template")
                        .where("template_id = ?", cardTemplate.getOldTemplateId())
                        .one();
                //移除
                List<String> payTypes = Arrays.asList(oldTemplate.getString("payTypes").split(","));
                payTypes.remove(payType.toString());
                DbChain.table("t_card_template")
                        .set("pay_type", StringUtils.join(payTypes, ","))
                        .where("template_id = ?", cardTemplate.getOldTemplateId())
                        .update();
            } finally {
                DataSourceKey.clear();
            }
            throw new ServiceException(e.getMessage());
        }
        List<WxPayScoreDetail> wxPayScoreDetails = BeanUtils.mapToList(result.getPlanDetailList(), WxPayScoreDetail.class);
        wxPayScoreDetails.forEach(item -> {
            item.setSysWxPayScoreId(wxPayScore.getId());
        });
        //批量保存计划详情
        SpringUtils.getBean(WxPayScoreDetailService.class).saveBatch(wxPayScoreDetails);
        //更新外部计划id
        wxPayScoreService.updateChain()
                .set(WX_PAY_SCORE.OUT_PLAN_ID,result.getPlanId())
                .where(WX_PAY_SCORE.ID.eq(wxPayScore.getId()))
                .update();
        //模板拓展
        CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
        cardTemplateExtend.setTemplateId(cardTemplate.getId())
                .setExtendId(wxPayScore.getId())
                .setExtendParamOne("1")
                .setPayType(payType);
        cardTemplateExtendService.save(cardTemplateExtend);
    }
}
