package com.spot.utils;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.spot.entity.ConfigCoinSymbol;
import com.spot.entity.ConfigSymbol;
import com.spot.entity.ConfigSymbolSlippage;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 常量定义类，包含本地缓存和业务常量
 *
 * @author jean
 * @date 2026-05-06
 */
public class Constant {

    /** 交易对配置缓存，30分钟过期 */
    public static final Cache<String, ConfigSymbol> SYMBOL_CONFIG_CACHE = Caffeine.newBuilder()
            .expireAfterWrite(30, TimeUnit.MINUTES)
            .build();

    /** 币种配置缓存，30分钟过期 */
    public static final Cache<String, ConfigCoinSymbol> COIN_SYMBOL_CONFIG_CACHE = Caffeine.newBuilder()
            .expireAfterWrite(30, TimeUnit.MINUTES)
            .build();

    /** 账户资产汇率缓存，5秒过期（行情实时变化） */
    public static final Cache<String, BigDecimal> ACCOUNT_ASSET_RATE_CACHE = Caffeine.newBuilder()
            .expireAfterWrite(5, TimeUnit.SECONDS)
            .build();


    /** USDT 币种符号 */
    public static final String COIN_SYMBOL_USDT = "USDT";

    /** 默认显示精度（币种配置未找到时使用） */
    public static final int DEFAULT_PRECISION = 8;

    /** 账户流水来源 - 订单系统 */
    public static final String ACCOUNT_RECORD_SOURCE_EX_ORDER = "ex_order";

    /** 账户流水来源 - 内部转账 */
    public static final String ACCOUNT_RECORD_SOURCE_INNER_TRANSFER = "exchange_inner_transfer";

    /** 账户流水来源 - 账户划转 */
    public static final String ACCOUNT_RECORD_SOURCE_ACCOUNT_TRANSFER = "exchange.account";

    /** 账户流水来源 - 提现记录 */
    public static final String ACCOUNT_RECORD_SOURCE_WITHDRAW = "transaction_withdraw_crypto";

    /** API 成功响应码 */
    public static final String API_SUCCESS_CODE = "0";

    // ==================== Kafka Topic 常量 ====================

    /** 撮合订单 Topic 前缀，完整 Topic = KAFKA_TOPIC_MATCH + symbol */
    public static final String KAFKA_TOPIC_MATCH = "SPOT_MATCH_";

    /** 交易结果 Topic 前缀，完整 Topic = KAFKA_TOPIC_TRADE + symbol */
    public static final String KAFKA_TOPIC_TRADE = "SPOT_TRADE_";

    /** 价格更新 Topic */
    public static final String KAFKA_TOPIC_PRICE = "SPOT_NEW_PRICE";

    /** 资产变动通知 Topic */
    public static final String KAFKA_TOPIC_CHANGE = "SPOT_CHANGE";

    /** 资金账户缓存更新 Topic（dage 系统监听） */
    public static final String KAFKA_TOPIC_TRADING_ACCOUNT_CHANGE = "trading-account-change";

    // ==================== 撮合引擎常量 ====================

    /** 系统撮合对手方订单ID（市价单无对手订单，使用0表示系统） */
    public static final long SYSTEM_ORDER_ID = 0L;

    /** 系统撮合对手方用户ID（市价单对手方为系统，使用1表示） */
    public static final int SYSTEM_USER_ID = 1;

    /** 小额余量检测倍数（剩余量 < 最小交易单位 * 2 时视为小额尾单） */
    public static final BigDecimal SMALL_REMAINDER_MULTIPLIER = new BigDecimal("2");

    /** 默认最小交易数量/金额（币种配置未找到时的兜底值） */
    public static final BigDecimal DEFAULT_MIN_TRADE_VOLUME = new BigDecimal("0.00000001");

    /** 撮合引擎缓存 Key 分隔符，格式：symbol_side */
    public static final String CACHE_KEY_SEPARATOR = "_";

    // ==================== 资金钱包常量 ====================

    /** 资金钱包未锁定状态（is_lock=0） */
    public static final Integer WALLET_IS_LOCK_NO = 0;

    /** 资金钱包已锁定状态（is_lock=1），锁定后禁止任何余额变动 */
    public static final Integer WALLET_IS_LOCK_YES = 1;

    // ==================== 资金流水方向常量 ====================

    /** 资金流水方向：转入（进账，对应 member_transaction.direction=0） */
    public static final int TRANSACTION_DIRECTION_IN = 0;

    /** 资金流水方向：转出（出账，对应 member_transaction.direction=1） */
    public static final int TRANSACTION_DIRECTION_OUT = 1;

    // ==================== 解冻任务常量 ====================

    /** 孤悬冻结检查任务执行间隔（毫秒），每分钟执行一次 */
    public static final long RELEASE_ORPHAN_FROZEN_INTERVAL_MS = 60_000L;

    /** 孤悬冻结检查每批次最大处理账户数，防止单次处理量过大 */
    public static final int RELEASE_ORPHAN_FROZEN_BATCH_SIZE = 500;

    /** 账户流水来源 - 系统自动解冻孤悬冻结 */
    public static final String ACCOUNT_RECORD_SOURCE_RELEASE_FROZEN = "release_orphan_frozen";

    // ==================== 通用开关状态常量 ====================

    /** 启用状态码（isOpen=1 表示启用） */
    public static final int IS_OPEN_ENABLED = 1;

    /** 禁用状态码（isOpen=0 表示禁用） */
    public static final int IS_OPEN_DISABLED = 0;

    /** 已发布状态码（publish=1 表示已发布上线） */
    public static final int PUBLISH_ENABLED = 1;

    // ==================== 滑点配置常量 ====================

    /** 滑点区间无上限标识（amount_max=-1 表示无上限） */
    public static final BigDecimal SLIPPAGE_AMOUNT_MAX_UNLIMITED = BigDecimal.valueOf(-1);

    // ==================== 定时任务常量 ====================

    /** 超时订单检查间隔（毫秒），30秒扫描一次 */
    public static final long ORDER_TIMEOUT_CHECK_INTERVAL_MS = 30_000L;

    /** 订单超时时间（分钟），超过此时间的 INIT/PENDING_CANCEL 订单将被自动撤单 */
    public static final long ORDER_TIMEOUT_MINUTES = 3L;
}
