package com.jeesharp.business.modules.marketing.application.support;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jeesharp.framework.exception.BizErrorException;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 店铺券核销动态令牌短时缓存（默认 60 秒，进程内内存缓存）。
 *
 * @author jeesharp
 * @since 2026-06-25
 */
@Component
public class MarketingVerifyTokenSupport {

    private static final long TTL_MS = 60_000L;
    private static final String QRCODE_PREFIX = "MKV";

    private final ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();

    /**
     * 生成并缓存核销令牌。
     */
    public MarketingVerifyTokenPayload issue(String memberCouponId, String memberId, String tenantId, String tenantCode) {
        if (StrUtil.hasBlank(memberCouponId, memberId, tenantId, tenantCode)) {
            throw new BizErrorException("生成核销码参数不完整");
        }
        String verifyToken = IdUtil.fastSimpleUUID();
        MarketingVerifyTokenPayload payload = new MarketingVerifyTokenPayload();
        payload.setVerifyToken(verifyToken);
        payload.setMemberCouponId(memberCouponId.trim());
        payload.setMemberId(memberId.trim());
        payload.setTenantId(tenantId.trim());
        payload.setTenantCode(tenantCode.trim());
        payload.setExpireAt(System.currentTimeMillis() + TTL_MS);
        cache.put(verifyToken, new CacheEntry(payload, payload.getExpireAt()));
        return payload;
    }

    public MarketingVerifyTokenPayload get(String verifyToken) {
        if (StrUtil.isBlank(verifyToken)) {
            return null;
        }
        String key = verifyToken.trim();
        CacheEntry entry = cache.get(key);
        if (entry == null) {
            return null;
        }
        if (entry.isExpired()) {
            cache.remove(key);
            return null;
        }
        return entry.payload();
    }

    public void remove(String verifyToken) {
        if (StrUtil.isBlank(verifyToken)) {
            return;
        }
        cache.remove(verifyToken.trim());
    }

    public String buildQrcodeContent(MarketingVerifyTokenPayload payload) {
        return QRCODE_PREFIX + "|" + payload.getTenantCode() + "|" + payload.getVerifyToken();
    }

    /**
     * 解析扫码内容中的 verifyToken（兼容纯 token 与 MKV|tenantCode|token 格式）。
     */
    public String parseVerifyToken(String rawContent) {
        if (StrUtil.isBlank(rawContent)) {
            return null;
        }
        String content = rawContent.trim();
        if (content.startsWith(QRCODE_PREFIX + "|")) {
            String[] parts = content.split("\\|");
            if (parts.length >= 3) {
                return parts[2].trim();
            }
        }
        if (JSONUtil.isTypeJSON(content)) {
            String token = JSONUtil.parseObj(content).getStr("verifyToken");
            return StrUtil.isBlank(token) ? null : token.trim();
        }
        return content;
    }

    /**
     * 解析扫码内容中的店铺租户编码（MKV|tenantCode|token 格式）。
     */
    public String parseTenantCode(String rawContent) {
        if (StrUtil.isBlank(rawContent)) {
            return null;
        }
        String content = rawContent.trim();
        if (content.startsWith(QRCODE_PREFIX + "|")) {
            String[] parts = content.split("\\|");
            if (parts.length >= 2 && StrUtil.isNotBlank(parts[1])) {
                return parts[1].trim();
            }
        }
        return null;
    }

    private record CacheEntry(MarketingVerifyTokenPayload payload, long expireAtMs) {

        boolean isExpired() {
            return System.currentTimeMillis() > expireAtMs;
        }
    }

    @Data
    public static class MarketingVerifyTokenPayload {

        private String verifyToken;

        private String memberCouponId;

        private String memberId;

        private String tenantId;

        private String tenantCode;

        private long expireAt;
    }
}
