package com.cyl.manager.marketing.service.impl;

import cn.felord.payment.wechat.enumeration.BusiFavorUseMethod;
import cn.felord.payment.wechat.enumeration.StockType;
import cn.felord.payment.wechat.v3.WechatApiProvider;
import cn.felord.payment.wechat.v3.WechatMarketingBusiFavorApi;
import cn.felord.payment.wechat.v3.WechatResponseEntity;
import cn.felord.payment.wechat.v3.model.busifavor.*;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyl.manager.marketing.domain.WechatStock;
import com.cyl.manager.marketing.mapper.WechatStockMapper;
import com.cyl.manager.marketing.service.IWechatStockService;
import com.cyl.manager.ums.domain.MemberWechat;
import com.cyl.wechat.WechatPayData;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.List;

@Service
@Slf4j
public class WechatStockServiceImpl implements IWechatStockService {

    @Autowired
    WechatApiProvider wechatApiProvider;

    @Autowired
    private WechatStockMapper wechatStockMapper;

    @Override
    public WechatStock selectWechatStockById(Long id) {
        return wechatStockMapper.selectById(id);
    }

    @Override
    public WechatStock selectWechatStockByStockId(String stockId) {
        QueryWrapper<WechatStock> qw = new QueryWrapper<>();
        if (stockId != null) {
            qw.eq("stock_id", stockId);
            return wechatStockMapper.selectOne(qw);
        }

        return null;
    }

    @Override
    public List<WechatStock> selectWechatStockList(WechatStock wechatStock) {
        return wechatStockMapper.selectList2(wechatStock);
    }

    @Override
    public int insertWechatStock(WechatStock wechatStock) {
        String stockType = wechatStock.getStockType();
        log.info("[创建优惠券]优惠券类型：" + stockType);

        String outRequestId = UUID.randomUUID().toString();

        Long userId = SecurityUtils.getUserId();
        wechatStock.setStockState("RUNNING");
        wechatStock.setCouponCodeMode("PLATFORM_MODE");

        wechatStock.setUseMethod("MINI_PROGRAMS");
        wechatStock.setOutRequestNo(outRequestId);

        wechatStock.setCreateBy(userId);
        wechatStock.setCreateTime(LocalDateTime.now());
        wechatStock.setUpdateBy(userId);
        wechatStock.setUpdateTime(LocalDateTime.now());

        if (stockType.equals(StockType.DISCOUNT.name())
                || stockType.equals(StockType.NORMAL.name())
                || stockType.equals(StockType.EXCHANGE.name())) {
            //发送微信商家券 与微信平台对接
            return sendWechatConpon(wechatStock);
        }

        String stockId = UUID.randomUUID().toString();
        wechatStock.setStockId(stockId);
        log.info("[创建优惠券]开始创建平台优惠券：" + wechatStock);

        return wechatStockMapper.insert(wechatStock);
    }

    private int sendWechatConpon(WechatStock wechatStock) {
        log.info("[创建优惠券]开始创建微信商家券：" + wechatStock);
        StockType stockType = StockType.valueOf(wechatStock.getStockType());

        String outRequestId = UUID.randomUUID().toString();

        BusiFavorCreateParams params = new BusiFavorCreateParams();

        params.setStockName(wechatStock.getStockName());
        params.setComment(wechatStock.getComment());
        params.setGoodsName(wechatStock.getGoodsName());
        params.setBelongMerchant(WechatPayData.merchantId);
        params.setStockType(stockType);

        CouponUseRule couponUseRule = new CouponUseRule();
        couponUseRule.setUseMethod(BusiFavorUseMethod.MINI_PROGRAMS);

        CouponAvailableTime couponAvailableTime = new CouponAvailableTime();

        couponAvailableTime.setAvailableEndTime( OffsetDateTime.of(wechatStock.getAvailableEndTime(), ZoneOffset.ofHours(0)));
        couponAvailableTime.setAvailableBeginTime( OffsetDateTime.of(wechatStock.getAvailableBeginTime(), ZoneOffset.ofHours(0)));
        couponAvailableTime.setAvailableDayAfterReceive(wechatStock.getAvailableDayAfterReceive());

        couponUseRule.setCouponAvailableTime(couponAvailableTime);

        BusiFavorNotifyConfig busiFavorNotifyConfig = new BusiFavorNotifyConfig();
        busiFavorNotifyConfig.setNotifyAppid(WechatPayData.miniProgramAppId);
        params.setNotifyConfig(busiFavorNotifyConfig);

        if (stockType == StockType.DISCOUNT) {
            DiscountCoupon discountCoupon = new DiscountCoupon();
            discountCoupon.setDiscountPercent(wechatStock.getDiscountPercent());
            discountCoupon.setTransactionMinimum(wechatStock.getTransactionMinimum());

            couponUseRule.setDiscountCoupon(discountCoupon);
        } else if (stockType == StockType.NORMAL) {
            FixedNormalCoupon fixedNormalCoupon = new FixedNormalCoupon();
            fixedNormalCoupon.setTransactionMinimum(wechatStock.getTransactionMinimum());
            fixedNormalCoupon.setDiscountAmount(wechatStock.getDiscountAmount());

            couponUseRule.setFixedNormalCoupon(fixedNormalCoupon);
        } else {
            log.error("[创建优惠券]暂不支持该类型的券");
            throw new ServiceException("[创建优惠券]暂不支持该类型的券：" + stockType.name());
        }

        couponUseRule.setMiniProgramsAppid(WechatPayData.miniProgramAppId);
        couponUseRule.setMiniProgramsPath("/path/index/index");

        params.setCouponUseRule(couponUseRule);

        StockSendRule stockSendRule = new StockSendRule();
        stockSendRule.setMaxCoupons(wechatStock.getMaxCoupons());
        stockSendRule.setMaxCouponsPerUser(wechatStock.getMaxCouponsPerUser());

        params.setStockSendRule(stockSendRule);
        params.setOutRequestNo(outRequestId);

        params.setCouponCodeMode(BusiFavorCreateParams.CouponCodeMode.WECHATPAY_MODE);

        log.info("【发送微信商户券请求参数】" + JSON.toJSONString(params));

        WechatMarketingBusiFavorApi wechatMarketingBusiFavorApi = wechatApiProvider.busiFavorApi("miniapp");

        WechatResponseEntity<ObjectNode> wechatResponseEntity = wechatMarketingBusiFavorApi.createStock(params);
        log.info("【发送微信商户券返回参数】" + JSON.toJSONString(wechatResponseEntity));

//        {
//            "httpStatus": 200,
//                "body": {
//            "create_time": "2024-04-28T21:37:18+08:00",
//                    "stock_id": "1262000000000051"
//        },
//            "4xxClientError": false,
//                "5xxServerError": false,
//                "1xxInformational": false,
//                "2xxSuccessful": true,
//                "3xxRedirection": false
//        }

        if (wechatResponseEntity.is2xxSuccessful()) {
            ObjectNode body = wechatResponseEntity.getBody();
            String stock_id = body.get("stock_id").toString();
            if (stock_id.contains("\"")) {
                stock_id = stock_id.replace("\"","");
            }

            wechatStock.setCouponCodeMode("WECHATPAY_MODE");
            wechatStock.setStockId(stock_id);

            return wechatStockMapper.insert(wechatStock);
        }

        throw new ServiceException("创建商户券失败：" + JSON.toJSONString(wechatResponseEntity));
    }

    @Override
    public int updateWechatStock(WechatStock wechatStock) {
        Long userId = SecurityUtils.getUserId();
        wechatStock.setUpdateBy(userId);
        wechatStock.setUpdateTime(LocalDateTime.now());
        return wechatStockMapper.update(wechatStock);
    }

    @Override
    public int deleteWechatStockByIds(Long[] ids) {
        return wechatStockMapper.deleteByIds(ids);
    }

    @Override
    public int deleteWechatStockById(Long id) {
        return wechatStockMapper.deleteById(id);
    }

    @Override
    public String getStockTitleByIds(List<String> list) {

        List<WechatStock> wechatStocks = wechatStockMapper.selectList(Wrappers.<WechatStock>lambdaQuery()
                .select(WechatStock::getStockName)
                .in(WechatStock::getId, list));

        StringBuffer buffer = new StringBuffer();

        for (WechatStock wechatStock : wechatStocks) {
            buffer.append(wechatStock.getStockName()).append(",");
        }

        return buffer.length() > 1 ? buffer.substring(0, buffer.length() - 1) : "";
    }
}
