package com.ruoyi.ss.card.service.impl;

import java.util.List;
import java.util.Optional;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.dy.DouYinAccessTokenUtil;
import com.ruoyi.ss.card.domain.GroupBuyingDTO;
import com.ruoyi.ss.userCard.domain.UserCard;
import com.ruoyi.ss.userCard.service.IUserCardService;
import com.ruoyi.ss.checkoff.domain.CheckoffRecords;
import com.ruoyi.ss.checkoff.service.ICheckoffRecordsService;
import com.ruoyi.ss.mapping.domain.StoreMappingVO;
import com.ruoyi.ss.mapping.service.IStoreMappingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.ss.card.mapper.SsCardMapper;
import com.ruoyi.ss.card.domain.SsCard;
import com.ruoyi.ss.card.domain.SsCardVO;
import com.ruoyi.ss.card.domain.SsCardQuery;
import com.ruoyi.ss.card.service.ISsCardService;

import static com.ruoyi.common.constant.ServiceConstants.CARD_STATUS_UNUSED;
import static com.ruoyi.common.constant.ServiceConstants.COUPON_GET_THIRD_PARTY_PURCHASE;

/**
 * 卡券Service业务层处理
 *
 * @author qzz
 * @date 2025-03-03
 */
@Service
public class SsCardServiceImpl implements ISsCardService
{
    private static final Logger log = LoggerFactory.getLogger(SsCardServiceImpl.class);

    @Autowired
    private SsCardMapper cardMapper;

    @Autowired
    private IStoreMappingService storeMappingService;

    @Value("${douyin.appKey}")
    private String appKey;

    @Value("${douyin.secret}")
    private String appSecret;

    @Autowired
    private ICheckoffRecordsService checkoffRecordsService;

    @Autowired
    private IUserCardService cardGetRecordsService;

    /**
     * 查询卡券
     *
     * @param couponId 卡券主键
     * @return 卡券
     */
    @Override
    public SsCardVO selectSsCardByCouponId(Long couponId)
    {
        return cardMapper.selectSsCardByCouponId(couponId);
    }

    /**
     * 根据skuId查询卡券
     *
     * @param skuId skuId
     * @return 卡券
     */
    @Override
    public SsCardVO selectSsCardBySkuId(String skuId) {
        return cardMapper.selectSsCardBySkuId(skuId);
    }

    /**
     * 查询卡券列表
     *
     * @param ssCard 卡券
     * @return 卡券
     */
    @Override
    public List<SsCardVO> selectSsCardList(SsCardQuery ssCard)
    {
        return cardMapper.selectSsCardList(ssCard);
    }

    /**
     * 新增卡券
     *
     * @param ssCard 卡券
     * @return 结果
     */
    @Override
    public int insertSsCard(SsCard ssCard)
    {
        ssCard.setCreateTime(DateUtils.getNowDate());
        return cardMapper.insertSsCard(ssCard);
    }

    /**
     * 修改卡券
     *
     * @param ssCard 卡券
     * @return 结果
     */
    @Override
    public int updateSsCard(SsCard ssCard)
    {
        return cardMapper.updateSsCard(ssCard);
    }

    /**
     * 批量删除卡券
     *
     * @param couponIds 需要删除的卡券主键
     * @return 结果
     */
    @Override
    public int deleteSsCardByCouponIds(Long[] couponIds)
    {
        return cardMapper.deleteSsCardByCouponIds(couponIds);
    }

    /**
     * 删除卡券信息
     *
     * @param couponId 卡券主键
     * @return 结果
     */
    @Override
    public int deleteSsCardByCouponId(Long couponId)
    {
        return cardMapper.deleteSsCardByCouponId(couponId);
    }

    /**
     * 验券准备
     */
    @Override
    public int prepare(GroupBuyingDTO dto) {
        StoreMappingVO storeMappingVO = storeMappingService.selectStoreMappingByStoreId(dto.getStoreId());
        String tpStoreId = storeMappingVO.getTpStoreId();
        String token = DouYinAccessTokenUtil.getToken(appKey, appSecret);

        String uri = "https://open.douyin.com/goodlife/v1/fulfilment/certificate/prepare/";

        // 获取二维码的短链数据
        String res = HttpUtil.get(dto.getEncryptedData());
        String encryptedDataUri = ReUtil.getGroup0(Validator.URL, res);

        // 解析 object_id
        String objectId = Optional.ofNullable(UrlBuilder.of(encryptedDataUri).getQuery().get("object_id"))
                .map(Object::toString)
                .orElseThrow(() -> new RuntimeException("二维码数据中未找到 object_id"));

        // 发起请求
        String result = HttpRequest.get(uri)
                .contentType("application/json")
                .header("access-token", token)
                .form("encrypted_data", objectId)
                .execute()
                .body();

        // 解析结果
        saveCheckoffRecords(result, tpStoreId, token);
        return 1;
    }

    private void saveCheckoffRecords(String result, String tpStoreId, String token) {
        JSONObject jsonObject = JSON.parseObject(result);
        JSONObject data = jsonObject.getJSONObject("data");

        // 确保 data 存在
        ServiceUtil.assertion(data == null || !"0".equals(data.getString("error_code")),
                "【验券准备】调用失败: " + (data != null ? data.getString("description") : "无错误描述"));

        JSONArray certificates = Optional.ofNullable(data.getJSONArray("certificates"))
                .orElseGet(() -> {
                    log.error("未找到有效的 certificate 信息");
                    return new JSONArray();
                });

        if (certificates.isEmpty()) {
            return;
        }

        JSONObject firstCertificate = certificates.getJSONObject(0);
        JSONObject amount = firstCertificate.getJSONObject("amount");

        // 避免空指针异常
        Integer originalAmount = amount != null ? amount.getInteger("original_amount") : 0;
        Integer listMarketAmount = amount != null ? amount.getInteger("list_market_amount") : 0;
        Integer payAmount = amount != null ? amount.getInteger("pay_amount") : 0;

        String verifyToken = data.getString("verify_token");
        String encryptedCode = firstCertificate.getString("encrypted_code");

        JSONObject sku = firstCertificate.getJSONObject("sku");
        String skuId = sku != null ? sku.getString("sku_id") : null;

        // 获取卡券信息
        SsCardVO ssCardVO = cardMapper.selectSsCardBySkuId(skuId);
        ServiceUtil.assertion(ssCardVO == null, "【验券准备】根据 sku_id 未查询到卡券");

        CheckoffRecords checkoffRecords = new CheckoffRecords();
        checkoffRecords.setCheckoffTime(DateUtils.getNowDate());
        checkoffRecords.setStatus("1");
        checkoffRecords.setEncryptedCode(encryptedCode);
        checkoffRecords.setPoiId(tpStoreId);
        checkoffRecords.setUserId(SecurityUtils.getUserId());
        checkoffRecords.setVerifyToken(verifyToken);
        checkoffRecords.setResult(result);
        checkoffRecords.setOriginalAmount(originalAmount);
        checkoffRecords.setListMarketAmount(listMarketAmount);
        checkoffRecords.setPayAmount(payAmount);
        checkoffRecords.setCardId(ssCardVO.getCouponId());
        checkoffRecords.setSkuId(skuId);

        int insertResult = checkoffRecordsService.insertCheckoffRecords(checkoffRecords);
        log.info("新建核销记录：{}", insertResult > 0 ? "成功" : "失败");
        ServiceUtil.assertion(insertResult == 0, "新建核销记录失败");

        // 核销接口
        verifyCertificate(checkoffRecords, token);

        // 创建卡券领取记录
        UserCard cardGetRecords = new UserCard();
        cardGetRecords.setStatus(CARD_STATUS_UNUSED);
        cardGetRecords.setUserId(SecurityUtils.getUserId());
        cardGetRecords.setCouponId(ssCardVO.getCouponId());
        cardGetRecords.setGetMethod(COUPON_GET_THIRD_PARTY_PURCHASE);
        cardGetRecords.setReceiveTime(DateUtils.getNowDate());
        cardGetRecords.setStartTime(DateUtils.getNowDate());
        cardGetRecords.setEndTime(DateUtils.addYears(DateUtils.getNowDate(), 1));

        int cardInsertResult = cardGetRecordsService.insertUserCard(cardGetRecords);
        log.info("新建卡券领取记录：{}", cardInsertResult > 0 ? "成功" : "失败");
        ServiceUtil.assertion(cardInsertResult == 0, "新建卡券领取记录失败");
    }

    private void verifyCertificate(CheckoffRecords checkoffRecords, String token) {
        String uri = "https://open.douyin.com/goodlife/v1/fulfilment/certificate/verify/";

        JSONObject verifyJson = new JSONObject();
        verifyJson.put("verify_token", checkoffRecords.getVerifyToken());
        verifyJson.put("poi_id", checkoffRecords.getPoiId());
        JSONArray encryptedCodeArray = new JSONArray();
        encryptedCodeArray.add(checkoffRecords.getEncryptedCode());

        verifyJson.put("encrypted_codes", encryptedCodeArray);
        log.info("verifyJson={}", JSON.toJSONString(verifyJson));

        String verifyResult = HttpRequest.post(uri)
                .contentType("application/json")
                .header("access-token", token)
                .body(verifyJson.toJSONString())
                .execute()
                .body();

        // 解析 JSON
        JSONObject resultJson = JSONObject.parseObject(verifyResult);
        JSONObject data1 = resultJson.getJSONObject("data");

        // 确保 data1 存在
        int errorCode = (data1 != null) ? data1.getIntValue("error_code") : -1;
        String errorMsg = (data1 != null) ? data1.getString("description") : "未知错误";

        ServiceUtil.assertion(errorCode != 0, "调验券接口失败: " + errorMsg);
    }



}
