package com.cpop.jambox.business.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.handler.TencentCosHandler;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.file.FileUtils;
import com.cpop.jambox.business.bo.CardTemplateUnionBo;
import com.cpop.jambox.business.bo.EasyLearnDigitalCurrencyBo;
import com.cpop.jambox.business.bo.EasyLearnOldContractBo;
import com.cpop.jambox.business.entity.BrandExtend;
import com.cpop.jambox.business.entity.CardTemplate;
import com.cpop.jambox.business.entity.CardTemplateExtend;
import com.cpop.jambox.business.entity.StoreExtend;
import com.cpop.jambox.business.mapper.CardTemplateMapper;
import com.cpop.jambox.business.service.BrandExtendService;
import com.cpop.jambox.business.service.CardTemplateExtendService;
import com.cpop.jambox.business.service.CardTemplateService;
import com.cpop.jambox.business.service.StoreExtendService;
import com.cpop.jambox.business.vo.CardTemplateInfoVo;
import com.cpop.jambox.business.vo.LearnNowPayLaterPlanDetailVo;
import com.cpop.jambox.business.vo.LearnNowPayLaterPlanVo;
import com.cpop.jambox.framework.tasks.LearnNowPayLaterTask;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.entity.WxPayScore;
import com.cpop.system.business.entity.WxPayScoreDetail;
import com.cpop.system.business.service.StoreService;
import com.cpop.system.business.service.WxPayScoreDetailService;
import com.cpop.system.business.service.WxPayScoreService;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.qcloud.cos.model.UploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.cpop.jambox.business.entity.table.BrandExtendTableDef.BRAND_EXTEND;
import static com.cpop.jambox.business.entity.table.CardTemplateExtendTableDef.CARD_TEMPLATE_EXTEND;
import static com.cpop.jambox.business.entity.table.CardTemplateTableDef.CARD_TEMPLATE;
import static com.cpop.jambox.business.entity.table.StoreExtendTableDef.STORE_EXTEND;
import static com.cpop.system.business.entity.table.WxPayScoreDetailTableDef.WX_PAY_SCORE_DETAIL;
import static com.cpop.system.business.entity.table.WxPayScoreTableDef.WX_PAY_SCORE;

/**
 * 果酱-课卡模板 服务层实现。
 *
 * @author DB
 * @since 2023-09-27
 */
@Service("cardTemplateService")
public class CardTemplateServiceImpl extends ServiceImpl<CardTemplateMapper, CardTemplate> implements CardTemplateService {

    /**
     * @descriptions 获取模板信息
     * @author DB
     * @date 2023/11/13 12:00
     * @param oldTemplateId 旧模板id
     * @param brandId 品牌id
     * @return: com.cpop.jambox.business.entity.CardTemplate
     */
    @Override
    public Row getOldTemplateInfo(String oldTemplateId, String brandId) {
        try {
            DataSourceKey.use("jambox");
            return Db.selectOneByQuery("t_card_template", QueryWrapper.create()
                    .select("template_id AS oldTemplateId", "store_id AS cloudStoreId", "open_status AS status", "name", "day AS validDay",
                            "start AS startDate", "end AS endDate", "price", "number AS classNumber", "week_appointment", "day_appointment",
                            "time_limit AS oldTemplateType", "type AS scopeUse", "pay_type", "template_qr_code AS qrCode", "is_member")
                    .from("t_card_template")
                    .where("template_id = ?", oldTemplateId));
        } finally {
            DataSourceKey.clear();
        }

    }

    /**
     * 添加课卡模板(整合)
     * @author DB
     * @since 2024/1/16
     * @param bo 请求参数
     * @return String 旧模板id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertCardTemplateUnion(CardTemplateUnionBo bo) {
        CardTemplate cardTemplate = BeanUtils.mapToClass(bo, CardTemplate.class);
        //品牌
        if (StringUtils.isNotBlank(bo.getBrandCloudId())){
            BrandExtendService brandExtendService = SpringUtils.getBean(BrandExtendService.class);
            BrandExtend brandExtend = brandExtendService.getOne(QueryWrapper.create().where(BRAND_EXTEND.BRAND_CLOUD_ID.eq(bo.getBrandCloudId())));
            cardTemplate.setBrandId(brandExtend.getBrandId());
        } else {
            //校区
            StoreExtend storeExtend = SpringUtils.getBean(StoreExtendService.class).getOne(QueryWrapper.create().where(STORE_EXTEND.STORE_CLOUD_ID.eq(bo.getStoreCloudId())));
            Store store = SpringUtils.getBean(StoreService.class).getById(storeExtend.getStoreId());
            cardTemplate.setStoreId(store.getId()).setBrandId(store.getBrandId());
        }
        this.save(cardTemplate);
        saveTemplateExtend(cardTemplate,bo);
        //次付
        if (bo.getPayType().contains(1)) {
            SpringUtils.getBean(LearnNowPayLaterTask.class).asyncCreateLearnNowPayLaterPlan(cardTemplate, bo.getLearnNowPayLaterPay(), 1);
        }
        //月付
        if (bo.getPayType().contains(5)) {
            SpringUtils.getBean(LearnNowPayLaterTask.class).asyncCreateLearnNowPayLaterPlan(cardTemplate, bo.getLearnNowPayLaterMonthPay(), 5);
        }
        if (bo.getPayType().contains(0) || bo.getPayType().contains(1) || bo.getPayType().contains(2) || bo.getPayType().contains(3) || bo.getPayType().contains(5)) {
            WxMaQrcodeService qrcodeService = SpringUtils.getBean(WxMaService.class).getQrcodeService();
            try {
                // 获取当前执行环境
                String active = SpringUtils.getActiveProfile();
                File qrCode = qrcodeService.createWxaCodeUnlimit(cardTemplate.getId(), "pages/pay/pay", false, StringUtils.equals(active, "prod") ? "release" : "trial", 430,
                        true, null, false);
                MultipartFile multipartFile = FileUtils.getInstance().getMultipartFile(qrCode);
                TencentCosHandler tencentCosHandler = SpringUtils.getBean(TencentCosHandler.class);
                UploadResult uploadResult = tencentCosHandler.cdnUpload(multipartFile);
                cardTemplate.setQrCode("https://" + uploadResult.getBucketName() + tencentCosHandler.getCdnUrl() + uploadResult.getKey());
                this.updateById(cardTemplate);
            } catch (WxErrorException | IOException e) {
                throw new ServiceException("生成支付码失败");
            }
        }
    }

    /**
     * 插入模板拓展
     * @author DB
     * @since 2024/1/19
     * @param cardTemplate 模板
     * @param bo 请求
     */
    private void saveTemplateExtend(CardTemplate cardTemplate, CardTemplateUnionBo bo) {
        List<CardTemplateExtend> cardTemplateExtends = new ArrayList<>();
        List<Integer> payTypeList = bo.getPayType();
        //普通微信支付
        if (payTypeList.contains(0)){
            CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
            cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(0);
            cardTemplateExtends.add(cardTemplateExtend);
        }
        //放心学合约支付
        if (payTypeList.contains(2)){
            CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
            EasyLearnOldContractBo easyLearnOldContract = bo.getEasyLearnOldContract();
            cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(2)
                    .setExtendParamOne(easyLearnOldContract.getStageNum().toString())
                    .setExtendParamTwo(easyLearnOldContract.getDeposit().toString())
                    .setExtendParamThree(easyLearnOldContract.getFirstBufferDay().toString());
            cardTemplateExtends.add(cardTemplateExtend);
        }
        //数字人民币支付
        if (payTypeList.contains(3)){
            CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
            EasyLearnDigitalCurrencyBo easyLearnDigitalCurrency = bo.getEasyLearnDigitalCurrency();
            cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(3)
                    .setExtendParamOne(easyLearnDigitalCurrency.getIsActivity().toString())
                    .setExtendParamTwo(easyLearnDigitalCurrency.getActivityCode())
                    .setExtendParamThree(easyLearnDigitalCurrency.getActivityDesc());
            cardTemplateExtends.add(cardTemplateExtend);
        }
        //线下支付
        if (payTypeList.contains(4)){
            CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
            cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(4);
            cardTemplateExtends.add(cardTemplateExtend);
        }
        SpringUtils.getBean(CardTemplateExtendService.class).saveBatch(cardTemplateExtends);
    }

    /**
     * 修改课卡模板(整合)
     * @author DB
     * @since 2024/1/18
     * @param bo 请求参数
     */
    @Override
    public void updateCardTemplateUnion(CardTemplateUnionBo bo) {
        CardTemplate cardTemplate = BeanUtils.mapToClass(bo, CardTemplate.class);
        this.update(cardTemplate, QueryWrapper.create().where(CARD_TEMPLATE.OLD_TEMPLATE_ID.eq(bo.getOldTemplateId())));
        CardTemplateExtendService cardTemplateExtendService = SpringUtils.getBean(CardTemplateExtendService.class);
        List<CardTemplateExtend> cardTemplateExtends = cardTemplateExtendService.list(QueryWrapper.create()
                .where(CARD_TEMPLATE_EXTEND.TEMPLATE_ID.eq(bo.getOldTemplateId())));
        updateTemplateExtend(cardTemplate, bo, cardTemplateExtends);
        //次付
        List<Integer> payTypeList = cardTemplateExtends.stream().map(CardTemplateExtend::getPayType).collect(Collectors.toList());
        if (bo.getPayType().contains(1) && !payTypeList.contains(1)) {
            SpringUtils.getBean(LearnNowPayLaterTask.class).asyncCreateLearnNowPayLaterPlan(cardTemplate, bo.getLearnNowPayLaterPay(), 1);
        }
        if (!bo.getPayType().contains(1) && payTypeList.contains(1)){
            //停用先学后付
            SpringUtils.getBean(CardTemplateExtendService.class).updateChain()
                    .set(CARD_TEMPLATE_EXTEND.EXTEND_PARAM_ONE, false)
                    .where(CARD_TEMPLATE_EXTEND.PAY_TYPE.eq(1))
                    .and(CARD_TEMPLATE_EXTEND.TEMPLATE_ID.eq(cardTemplate.getId()))
                    .update();
        }
        //月付
        if (bo.getPayType().contains(5) && !payTypeList.contains(5)) {
            SpringUtils.getBean(LearnNowPayLaterTask.class).asyncCreateLearnNowPayLaterPlan(cardTemplate, bo.getLearnNowPayLaterMonthPay(), 5);
        }
        if (!bo.getPayType().contains(1) && payTypeList.contains(1)){
            //停用先学后付
            SpringUtils.getBean(CardTemplateExtendService.class).updateChain()
                    .set(CARD_TEMPLATE_EXTEND.EXTEND_PARAM_ONE, false)
                    .where(CARD_TEMPLATE_EXTEND.PAY_TYPE.eq(5))
                    .and(CARD_TEMPLATE_EXTEND.TEMPLATE_ID.eq(cardTemplate.getId()))
                    .update();
        }
    }

    /**
     * 更新模板拓展
     * @author DB
     * @since 2024/1/19
     * @param cardTemplate 模板
     * @param bo 请求
     */
    private void updateTemplateExtend(CardTemplate cardTemplate, CardTemplateUnionBo bo, List<CardTemplateExtend> cardTemplateExtends) {
        List<Integer> payTypeList = bo.getPayType();
        Map<Integer, CardTemplateExtend> existExtends = cardTemplateExtends.stream().collect(Collectors.toMap(CardTemplateExtend::getPayType, item -> item));
        List<Integer> removePayTypes = new ArrayList<>();
        //普通微信支付
        if (payTypeList.contains(0)) {
            if (existExtends.get(0) == null) {
                CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
                cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(0);
                cardTemplateExtends.add(cardTemplateExtend);
            }
        } else {
            removePayTypes.add(0);
        }
        //放心学旧合约支付
        if (payTypeList.contains(2)) {
            CardTemplateExtend cardTemplateExtend;
            EasyLearnOldContractBo easyLearnOldContract = bo.getEasyLearnOldContract();
            if (existExtends.get(2) == null) {
                cardTemplateExtend = new CardTemplateExtend();
                cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(2)
                        .setExtendParamOne(easyLearnOldContract.getStageNum().toString())
                        .setExtendParamTwo(easyLearnOldContract.getDeposit().toString())
                        .setExtendParamThree(easyLearnOldContract.getFirstBufferDay().toString());
            } else {
                cardTemplateExtend = existExtends.get(2);
                cardTemplateExtend.setExtendParamOne(easyLearnOldContract.getStageNum().toString())
                        .setExtendParamTwo(easyLearnOldContract.getDeposit().toString())
                        .setExtendParamThree(easyLearnOldContract.getFirstBufferDay().toString());
            }
            cardTemplateExtends.add(cardTemplateExtend);
        } else {
            removePayTypes.add(2);
        }
        //数字人民币支付
        if (payTypeList.contains(3)){
            CardTemplateExtend cardTemplateExtend;
            EasyLearnDigitalCurrencyBo easyLearnDigitalCurrency = bo.getEasyLearnDigitalCurrency();
            if (existExtends.get(3) == null) {
                cardTemplateExtend = new CardTemplateExtend();
                cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(3)
                        .setExtendParamOne(easyLearnDigitalCurrency.getIsActivity().toString())
                        .setExtendParamTwo(easyLearnDigitalCurrency.getActivityCode())
                        .setExtendParamThree(easyLearnDigitalCurrency.getActivityDesc());
            } else {
                cardTemplateExtend = existExtends.get(3);
                cardTemplateExtend.setExtendParamOne(easyLearnDigitalCurrency.getIsActivity().toString())
                        .setExtendParamTwo(easyLearnDigitalCurrency.getActivityCode())
                        .setExtendParamThree(easyLearnDigitalCurrency.getActivityDesc());
            }
            cardTemplateExtends.add(cardTemplateExtend);
        } else {
            removePayTypes.add(3);
        }
        //线下支付
        if (payTypeList.contains(4)) {
            CardTemplateExtend cardTemplateExtend = new CardTemplateExtend();
            cardTemplateExtend.setTemplateId(cardTemplate.getId()).setPayType(4);
            cardTemplateExtends.add(cardTemplateExtend);
        } else {
            removePayTypes.add(4);
        }
        CardTemplateExtendService cardTemplateExtendService = SpringUtils.getBean(CardTemplateExtendService.class);
        cardTemplateExtendService.saveBatch(cardTemplateExtends);
        cardTemplateExtendService.updateChain()
                .where(CARD_TEMPLATE_EXTEND.TEMPLATE_ID.eq(cardTemplate.getId()))
                .and(CARD_TEMPLATE_EXTEND.PAY_TYPE.in(removePayTypes))
                .remove();
    }

    /**
     * 获取支付分计划
     * @author DB
     * @since 2024/1/18
     * @param oldTemplateId 旧模板id
     * @param isMonth 是否月付
     * @return LearnNowPayLaterPlanDetailVo
     */
    @Override
    public LearnNowPayLaterPlanVo getWxPayScorePlan(String oldTemplateId,String templateId, Boolean isMonth) {
        CardTemplate cardTemplate;
        if (StringUtils.isNotBlank(templateId)) {
            cardTemplate = this.queryChain().where(CARD_TEMPLATE.OLD_TEMPLATE_ID.eq(oldTemplateId)).one();
        } else {
            cardTemplate = this.queryChain().where(CARD_TEMPLATE.ID.eq(templateId)).one();
        }
        CardTemplateExtendService cardTemplateExtendService = SpringUtils.getBean(CardTemplateExtendService.class);
        CardTemplateExtend cardTemplateExtend = cardTemplateExtendService.getOne(QueryWrapper.create()
                .where(CARD_TEMPLATE_EXTEND.TEMPLATE_ID.eq(cardTemplate.getId()))
                .and(CARD_TEMPLATE_EXTEND.PAY_TYPE.eq(isMonth ? 5 : 1)));
        WxPayScore wxPayScore = SpringUtils.getBean(WxPayScoreService.class).getOne(QueryWrapper.create()
                .where(WX_PAY_SCORE.ID.eq(cardTemplateExtend.getExtendId())));
        LearnNowPayLaterPlanVo vo = BeanUtils.mapToClass(wxPayScore, LearnNowPayLaterPlanVo.class);
        List<WxPayScoreDetail> wxPayScoreDetails = SpringUtils.getBean(WxPayScoreDetailService.class).list(QueryWrapper.create()
                .where(WX_PAY_SCORE_DETAIL.SYS_WX_PAY_SCORE_ID.eq(vo.getId())));
        List<LearnNowPayLaterPlanDetailVo> detailVos = BeanUtils.mapToList(wxPayScoreDetails, LearnNowPayLaterPlanDetailVo.class);
        vo.setPlanDetailList(detailVos);
        return vo;
    }

    /**
     * 获取模板信息
     * @author DB
     * @since 2024/1/22
     * @param id 主键
     */
    @Override
    public CardTemplateInfoVo getCardTemplateInfo(String id, String oldTemplateId) {
        //TODO: 模板详情信息调整
        CardTemplateInfoVo vo;
        if (StringUtils.isNotBlank(id)) {
            vo = this.getOneAs(QueryWrapper.create().where(CARD_TEMPLATE.ID.eq(id))
                    , CardTemplateInfoVo.class);
        } else {
            vo = this.getOneAs(QueryWrapper.create().where(CARD_TEMPLATE.OLD_TEMPLATE_ID.eq(oldTemplateId))
                    , CardTemplateInfoVo.class);
        }
        //获取模板拓展
        List<Integer> payTypeList = SpringUtils.getBean(CardTemplateExtendService.class).queryChain()
                .where(CARD_TEMPLATE_EXTEND.TEMPLATE_ID.eq(vo.getId()))
                .list().stream().map(CardTemplateExtend::getPayType)
                .collect(Collectors.toList());
        vo.setPayType(payTypeList);
        return vo;
    }

}
