package constants

import "fmt"

// ========================================
// 认证相关 Redis Key
// ========================================

// RedisAuthTokenKey 生成访问令牌的 Redis 键
// 用途：存储用户 access token 信息
// 过期时间：24 小时（可配置）
func RedisAuthTokenKey(token string) string {
	return fmt.Sprintf("auth:token:%s", token)
}

// RedisAgentOpenAPINonceKey 生成代理开放接口 nonce 防重放 Redis 键
// 用途：记录账号在签名时间窗内已使用的随机串，防止重复请求
// 过期时间：与开放接口签名时间窗一致
func RedisAgentOpenAPINonceKey(account, nonce string) string {
	return fmt.Sprintf("agent_open_api:nonce:%s:%s", account, nonce)
}

// RedisRefreshTokenKey 生成刷新令牌的 Redis 键
// 用途：存储用户 refresh token 信息
// 过期时间：7 天（可配置）
func RedisRefreshTokenKey(token string) string {
	return fmt.Sprintf("auth:refresh:%s", token)
}

// RedisUserTokensKey 生成用户令牌列表的 Redis 键
// 用途：维护用户的所有有效 token 列表（Set 结构）
// 过期时间：7 天（可配置）
func RedisUserTokensKey(userID uint) string {
	return fmt.Sprintf("auth:user:%d:tokens", userID)
}

// RedisRateLimitKey 生成限流的 Redis 键
func RedisRateLimitKey(ip string) string {
	return fmt.Sprintf("ratelimit:%s", ip)
}

// RedisTaskLockKey 生成任务锁的 Redis 键
// 用途：幂等性控制，防止重复执行
// 过期时间：24 小时
func RedisTaskLockKey(requestID string) string {
	return fmt.Sprintf("task:lock:%s", requestID)
}

// RedisTaskStatusKey 生成任务状态的 Redis 键
// 用途：存储任务执行状态
// 过期时间：7 天
func RedisTaskStatusKey(taskID string) string {
	return fmt.Sprintf("task:status:%s", taskID)
}

// RedisExportDispatchLockKey 生成导出 dispatch 执行锁的 Redis 键
// 用途：防止同一导出任务并发执行 dispatch
// 过期时间：5 分钟
func RedisExportDispatchLockKey(taskID uint) string {
	return fmt.Sprintf("export:dispatch:lock:%d", taskID)
}

// RedisExportShardLockKey 生成导出分片执行锁的 Redis 键
// 用途：防止同一分片被多个 Worker 并发处理
// 过期时间：10 分钟
func RedisExportShardLockKey(taskID, shardID uint) string {
	return fmt.Sprintf("export:shard:lock:%d:%d", taskID, shardID)
}

// RedisExportFinalizeLockKey 生成导出 finalize 执行锁的 Redis 键
// 用途：防止同一导出任务并发执行 finalize
// 过期时间：2 分钟
func RedisExportFinalizeLockKey(taskID uint) string {
	return fmt.Sprintf("export:finalize:lock:%d", taskID)
}

// RedisShopSubordinatesKey 生成店铺下级 ID 列表的 Redis 键
// 用途：缓存递归查询的下级店铺 ID 列表
// 过期时间：30 分钟
func RedisShopSubordinatesKey(shopID uint) string {
	return fmt.Sprintf("shop:subordinates:%d", shopID)
}

// ========================================
// 个人客户认证相关 Redis Key
// ========================================

// RedisPersonalCustomerTokenKey 生成个人客户登录令牌的 Redis 键
// 用途：有状态 JWT，存储当前有效 token 字符串，支持服务端主动失效
// 过期时间：与 JWT 过期时间一致
func RedisPersonalCustomerTokenKey(customerID uint) string {
	return fmt.Sprintf("personal:customer:token:%d", customerID)
}

// RedisClientAuthRateLimitIPKey 生成 C 端资产验证 IP 限流键
// 用途：A1 接口 IP 级限频 30 次/分钟
// 过期时间：1 分钟
func RedisClientAuthRateLimitIPKey(ip string) string {
	return fmt.Sprintf("client:auth:ratelimit:ip:%s", ip)
}

// RedisClientSendCodePhoneLimitKey 生成验证码手机号冷却键
// 用途：A4 接口同手机号 60 秒冷却
// 过期时间：60 秒
func RedisClientSendCodePhoneLimitKey(phone string) string {
	return fmt.Sprintf("client:auth:sendcode:phone:limit:%s", phone)
}

// RedisClientSendCodeIPHourKey 生成验证码 IP 小时限流键
// 用途：A4 接口同 IP 每小时 20 次
// 过期时间：1 小时
func RedisClientSendCodeIPHourKey(ip string) string {
	return fmt.Sprintf("client:auth:sendcode:ip:hour:%s", ip)
}

// RedisClientSendCodePhoneDayKey 生成验证码手机号日限流键
// 用途：A4 接口同手机号每日 10 次
// 过期时间：当日剩余时间
func RedisClientSendCodePhoneDayKey(phone string) string {
	return fmt.Sprintf("client:auth:sendcode:phone:day:%s", phone)
}

// ========================================
// 验证码相关 Redis Key
// ========================================

// RedisVerificationCodeKey 生成验证码的 Redis 键
// 用途：存储手机验证码
// 过期时间：5 分钟
func RedisVerificationCodeKey(phone string) string {
	return fmt.Sprintf("verification:code:%s", phone)
}

// RedisVerificationCodeLimitKey 生成验证码发送频率限制的 Redis 键
// 用途：限制验证码发送频率
// 过期时间：60 秒
func RedisVerificationCodeLimitKey(phone string) string {
	return fmt.Sprintf("verification:limit:%s", phone)
}

// ========================================
// 钱包相关 Redis Key
// ========================================

// RedisWalletLockKey 生成钱包操作锁的 Redis 键
// 用途：钱包余额变更时的分布式锁，防止并发冲突
// 过期时间：10 秒
func RedisWalletLockKey(walletID uint) string {
	return fmt.Sprintf("wallet:lock:%d", walletID)
}

// RedisWalletBalanceKey 生成钱包余额缓存的 Redis 键
// 用途：缓存钱包余额，减少数据库查询
// 过期时间：5 分钟
func RedisWalletBalanceKey(walletID uint) string {
	return fmt.Sprintf("wallet:balance:%d", walletID)
}

// RedisRechargeOrderKey 生成充值订单缓存的 Redis 键
// 用途：充值订单状态查询缓存
// 过期时间：1 小时
func RedisRechargeOrderKey(rechargeNo string) string {
	return fmt.Sprintf("recharge:order:%s", rechargeNo)
}

// RedisWalletTransactionKey 生成钱包交易幂等性的 Redis 键
// 用途：防止重复交易
// 过期时间：24 小时
func RedisWalletTransactionKey(requestID string) string {
	return fmt.Sprintf("wallet:transaction:%s", requestID)
}

// ========================================
// 标签相关 Redis Key
// ========================================

// RedisTagCacheKey 生成标签缓存的 Redis 键
// 用途：缓存热门标签列表
// 过期时间：1 小时
func RedisTagCacheKey() string {
	return "tag:cache:list"
}

// RedisResourceTagsKey 生成资源标签关联缓存的 Redis 键
// 用途：缓存资源的标签列表
// 过期时间：30 分钟
func RedisResourceTagsKey(resourceType string, resourceID uint) string {
	return fmt.Sprintf("resource:tags:%s:%d", resourceType, resourceID)
}

// ========================================
// 权限相关 Redis Key
// ========================================

// RedisUserPermissionsKey 生成用户权限列表缓存的 Redis 键
// 用途：缓存用户的所有权限列表（包含 permCode 和 platform 信息）
// 格式：JSON 数组 [{"perm_code":"user:list","platform":"web"},...]
// 过期时间：30 分钟
func RedisUserPermissionsKey(userID uint) string {
	return fmt.Sprintf("permission:user:%d:list", userID)
}

// ========================================
// 佣金统计相关 Redis Key
// ========================================

// RedisCommissionStatsKey 生成佣金统计缓存的 Redis 键
// 用途：缓存梯度返佣统计数据（Hash 结构: total_count, total_amount）
// 过期时间：周期结束后 7 天
func RedisCommissionStatsKey(allocationID uint, period string) string {
	return fmt.Sprintf("commission:stats:%d:%s", allocationID, period)
}

// RedisCommissionStatsLockKey 生成佣金统计同步锁的 Redis 键
// 用途：定时同步任务的分布式锁，防止并发同步
// 过期时间：5 分钟
func RedisCommissionStatsLockKey() string {
	return "commission:stats:sync:lock"
}

// ========================================
// 系列分配相关 Redis Key
// ========================================

// RedisShopSeriesAllocationKey 生成店铺系列分配缓存的 Redis 键
// 用途：缓存店铺+系列的分配配置
// 过期时间：30 分钟
func RedisShopSeriesAllocationKey(shopID, seriesID uint) string {
	return fmt.Sprintf("shop_series_alloc:%d:%d", shopID, seriesID)
}

// ========================================
// 轮询系统相关 Redis Key
// ========================================

// RedisPollingQueueRealnameKey 生成实名检查轮询队列的 Redis 键
// 用途：Sorted Set 存储待检查实名状态的卡，Score 为下次检查的 Unix 时间戳
// 过期时间：无（持久化数据）
func RedisPollingQueueRealnameKey() string {
	return "polling:queue:realname"
}

// RedisPollingQueueCarddataKey 生成卡流量检查轮询队列的 Redis 键
// 用途：Sorted Set 存储待检查流量的卡，Score 为下次检查的 Unix 时间戳
// 过期时间：无（持久化数据）
func RedisPollingQueueCarddataKey() string {
	return "polling:queue:carddata"
}

// RedisPollingQueuePackageKey 生成套餐检查轮询队列的 Redis 键
// 用途：Sorted Set 存储待检查套餐的卡，Score 为下次检查的 Unix 时间戳
// 过期时间：无（持久化数据）
func RedisPollingQueuePackageKey() string {
	return "polling:queue:package"
}

// RedisPollingCardInfoKey 生成卡信息缓存的 Redis 键
// 用途：Hash 存储卡的基本信息和轮询状态
// 过期时间：7 天
func RedisPollingCardInfoKey(cardID uint) string {
	return fmt.Sprintf("polling:card:%d", cardID)
}

// RedisPollingConfigsCacheKey 生成轮询配置缓存的 Redis 键
// 用途：String 存储所有轮询配置（JSON 格式）
// 过期时间：10 分钟
func RedisPollingConfigsCacheKey() string {
	return "polling:configs"
}

// RedisPollingConfigCardsKey 生成配置匹配索引的 Redis 键
// 用途：Set 存储匹配该配置的所有卡 ID
// 过期时间：1 小时
func RedisPollingConfigCardsKey(configID uint) string {
	return fmt.Sprintf("polling:config:cards:%d", configID)
}

// RedisPollingConcurrencyConfigKey 生成并发控制配置的 Redis 键
// 用途：String 存储任务类型的最大并发数
// 过期时间：无（持久化配置）
func RedisPollingConcurrencyConfigKey(taskType string) string {
	return fmt.Sprintf("polling:concurrency:config:%s", taskType)
}

// RedisPollingConcurrencyCurrentKey 生成并发控制当前值的 Redis 键
// 用途：String 存储任务类型的当前并发数（计数器）
// 过期时间：无（实时数据）
func RedisPollingConcurrencyCurrentKey(taskType string) string {
	return fmt.Sprintf("polling:concurrency:current:%s", taskType)
}

// RedisPollingManualQueueKey 生成手动触发队列的 Redis 键
// 用途：List 存储手动触发的卡 ID（FIFO 队列）
// 过期时间：无（临时队列）
func RedisPollingManualQueueKey(taskType string) string {
	return fmt.Sprintf("polling:manual:%s", taskType)
}

// RedisPollingManualDedupeKey 生成手动触发去重的 Redis 键
// 用途：Set 存储已加入手动触发队列的卡 ID（用于去重）
// 过期时间：24小时（与日限制周期对齐）
func RedisPollingManualDedupeKey(taskType string) string {
	return fmt.Sprintf("polling:manual:dedupe:%s", taskType)
}

// RedisPollingStatsKey 生成监控统计的 Redis 键
// 用途：Hash 存储监控指标（成功数、失败数、总耗时等）
// 过期时间：无（持久化统计）
func RedisPollingStatsKey(taskType string) string {
	return fmt.Sprintf("polling:stats:%s", taskType)
}

// RedisPollingInitProgressKey 生成初始化进度的 Redis 键
// 用途：Hash 存储初始化进度信息（总数、已处理数、状态）
// 过期时间：无（初始化完成后自动删除）
func RedisPollingInitProgressKey() string {
	return "polling:init:progress"
}

// ========================================
// 复机并发保护相关 Redis Key
// ========================================

// RedisCardResumeLockKey 生成卡复机操作分布式锁的 Redis 键
// 用途：防止同一张卡并发触发多次 gateway.StartCard
// 过期时间：30 秒
func RedisCardResumeLockKey(cardID uint) string {
	return fmt.Sprintf("card:resume:lock:%d", cardID)
}

// ========================================
// 套餐激活锁相关键
// ========================================

// RedisPackageActivationLockKey 生成套餐激活分布式锁的 Redis 键
// 用途：防止同一载体的套餐激活任务并发执行（排队激活、首次实名激活）
// 过期时间：30秒（任务执行时间）
func RedisPackageActivationLockKey(carrierType string, carrierID uint) string {
	return fmt.Sprintf("package:activation:lock:%s:%d", carrierType, carrierID)
}

// ========================================
// 列表计数缓存 Redis Key
// ========================================

// RedisListCountKey 列表查询计数缓存键
// 用途：缓存分页列表的 COUNT(*) 结果，避免每次翻页重复全表计数
// 过期时间：30 秒
func RedisListCountKey(table string, version int64, userID uint, scopeHash string, filterHash string) string {
	return fmt.Sprintf("list_count:v2:%s:%d:%d:%s:%s", table, version, userID, scopeHash, filterHash)
}

// RedisListCountVersionKey 列表查询计数缓存版本键
// 用途：数据变更后递增版本，让旧 COUNT(*) 缓存立即失效
func RedisListCountVersionKey(table string) string {
	return fmt.Sprintf("list_count_version:%s", table)
}

// ========================================
// 订单幂等性相关 Redis Key
// ========================================

// RedisOrderIdempotencyKey 生成订单创建幂等性检测的 Redis 键
// 用途：防止相同买家在短时间内对同一载体重复下单（SETNX 快速拒绝）
// 过期时间：3 分钟
func RedisOrderIdempotencyKey(businessKey string) string {
	return fmt.Sprintf("order:idempotency:%s", businessKey)
}

// RedisOrderCreateLockKey 生成订单创建分布式锁的 Redis 键
// 用途：防止同一载体的订单创建并发执行
// 过期时间：10 秒
func RedisOrderCreateLockKey(carrierType string, carrierID uint) string {
	return fmt.Sprintf("order:create:lock:%s:%d", carrierType, carrierID)
}

// ========================================
// 客户端购买相关 Redis Key
// ========================================

// RedisClientPurchaseIdempotencyKey 生成客户端套餐购买幂等性检测的 Redis 键
// 用途：防止同一个人客户对同一资产重复提交购买请求（SETNX 快速拒绝）
// 过期时间：3 分钟
func RedisClientPurchaseIdempotencyKey(businessKey string) string {
	return fmt.Sprintf("client:purchase:idempotency:%s", businessKey)
}

// RedisClientPurchaseLockKey 生成客户端套餐购买分布式锁的 Redis 键
// 用途：防止同一资产的购买请求并发执行
// 过期时间：10 秒
func RedisClientPurchaseLockKey(assetType string, assetID uint) string {
	return fmt.Sprintf("client:purchase:lock:%s:%d", assetType, assetID)
}

// ========================================
// 设备保护期相关 Redis Key
// ========================================

// RedisDeviceProtectKey 生成设备保护期 Redis 键
// action: "stop"（停机保护期）或 "start"（复机保护期），两者互斥
// 过期时间：DeviceProtectPeriodDuration（1 小时）
func RedisDeviceProtectKey(deviceID uint, action string) string {
	return fmt.Sprintf("protect:device:%d:%s", deviceID, action)
}

// RedisDeviceRefreshCooldownKey 生成设备刷新冷却期 Redis 键
// 用途：防止同一设备短时间内多次调网关刷新（限频）
// 过期时间：DeviceRefreshCooldownDuration（30 秒）
func RedisDeviceRefreshCooldownKey(deviceID uint) string {
	return fmt.Sprintf("refresh:cooldown:device:%d", deviceID)
}

// ========================================
// 轮询保护期队列 Redis Key
// ========================================

// RedisPollingQueueProtectKey 保护期一致性检查轮询队列键
// 用途：存储需要进行保护期一致性检查的卡 ID（ZSet，按时间排序）
func RedisPollingQueueProtectKey() string {
	return "polling:queue:protect"
}

// ========================================
// 微信配置相关 Redis Key
// ========================================

// RedisWechatConfigActiveKey 生效支付配置缓存键
// 用途：缓存当前激活的微信参数配置（JSON 或 "none" 空标记）
// 过期时间：5 分钟（有配置）/ 1 分钟（空标记）
func RedisWechatConfigActiveKey() string {
	return "wechat:config:active"
}

// ========================================
// 流量日缓冲相关 Redis Key
// ========================================

// RedisCardDailyTrafficKey 生成卡日流量缓冲的 Redis 键
// 用途：INCRBYFLOAT 累计当日流量增量，每日落盘任务消费后删除
// 过期时间：48 小时
func RedisCardDailyTrafficKey(cardID uint, date string) string {
	return fmt.Sprintf("traffic:daily:%d:%s", cardID, date)
}

// RedisPackageUsageRemainderKey 生成套餐扣减流量小数余量缓存键
// 用途：缓存载体维度的 <1MB 小数余量，累计后再触发整数 MB 扣减
// 过期时间：7 天
func RedisPackageUsageRemainderKey(carrierType string, carrierID uint) string {
	return fmt.Sprintf("package:usage:remainder:%s:%d", carrierType, carrierID)
}

// RedisCardTrafficSyncLockKey 生成卡流量同步锁 Redis 键
// 用途：串行化轮询与手动刷新，避免同一上游读数被重复扣减套餐流量
// 过期时间：10 分钟
func RedisCardTrafficSyncLockKey(cardID uint) string {
	return fmt.Sprintf("traffic:sync:lock:card:%d", cardID)
}

// ========================================
// 轮询分片队列相关 Redis Key
// ========================================

// RedisPollingShardQueueKey 轮询分片队列 Key
// shardID: 分片编号（0 到 N-1）
// taskType: 任务类型（realname/carddata/package/protect）
// 格式：polling:shard:{shardID}:queue:{taskType}
func RedisPollingShardQueueKey(shardID int, taskType string) string {
	return fmt.Sprintf("polling:shard:%d:queue:%s", shardID, taskType)
}

// RedisPollingRealnameReversalCountKey 实名逆转连续计数器，防止上游单次误报触发停机
// TTL: 10分钟
func RedisPollingRealnameReversalCountKey(cardID uint) string {
	return fmt.Sprintf("polling:card:realname:reversal:%d", cardID)
}

// RedisCardObservationSeriesKey 返回同场景观测序列合并键。
func RedisCardObservationSeriesKey(scene, resourceType, resourceID, syncType string) string {
	return fmt.Sprintf("cardsync:series:%s:%s:%s:%s", scene, resourceType, resourceID, syncType)
}

// RedisCardObservationSeriesIndexKey 返回同资源、同步类型的活跃序列索引键。
func RedisCardObservationSeriesIndexKey(resourceType, resourceID, syncType string) string {
	return fmt.Sprintf("cardsync:series:index:%s:%s:%s", resourceType, resourceID, syncType)
}

// RedisCardObservationSeriesCompletedKey 返回序列提前完成标记键。
func RedisCardObservationSeriesCompletedKey(seriesID string) string {
	return fmt.Sprintf("cardsync:series:completed:%s", seriesID)
}

// RedisCardObservationAttemptKey 返回 series_id + attempt 幂等键。
func RedisCardObservationAttemptKey(seriesID string, attempt int) string {
	return fmt.Sprintf("cardsync:attempt:%s:%d", seriesID, attempt)
}

// RedisCardObservationScheduleKey 返回固定阶梯任务的入队幂等键。
func RedisCardObservationScheduleKey(seriesID string, attempt int) string {
	return fmt.Sprintf("cardsync:schedule:%s:%d", seriesID, attempt)
}

// RedisCardObservationInflightKey 返回一次实际 Gateway 请求的互斥键。
func RedisCardObservationInflightKey(provider, syncType, resourceID string) string {
	return fmt.Sprintf("cardsync:inflight:%s:%s:%s", provider, syncType, resourceID)
}

// RedisCardObservationLastRequestKey 返回运营商接入与同步类型的最近请求时间键。
func RedisCardObservationLastRequestKey(provider, syncType, resourceID string) string {
	return fmt.Sprintf("cardsync:last_request:%s:%s:%s", provider, syncType, resourceID)
}

// RedisPollingDeviceOpLockKey 设备维度停复机操作锁 Key
// 防止设备下多张卡并发触发 EvaluateAndAct 导致重复 Gateway 调用
// TTL 建议 30 秒（覆盖 stopDeviceCards/resumeDeviceCards 最长执行时间）
// 格式：polling:device:op_lock:{deviceID}
func RedisPollingDeviceOpLockKey(deviceID uint) string {
	return fmt.Sprintf("polling:device:op_lock:%d", deviceID)
}

// RedisPollingSchedulerHeartbeatKey 轮询调度器心跳 Key
// 调度器每次 tick 写入当前时间戳，TTL=2s
// 告警规则：key 不存在超过 5s 视为调度器停止运行
func RedisPollingSchedulerHeartbeatKey() string {
	return "polling:scheduler:heartbeat"
}

// RedisPollingConfigChangedChannel 轮询配置变更 Pub/Sub 频道
// 用途：API 进程发布配置变更事件，Worker 进程订阅后立即刷新内存缓存
// 消息内容：事件类型字符串（"created"/"updated"/"deleted"），仅用于日志，不影响逻辑
func RedisPollingConfigChangedChannel() string {
	return "polling:config:changed"
}

// ========================================
// 系统全局配置 Redis Key
// ========================================

// RedisSystemOperationPasswordKey 全局操作密码 Redis 键
// 用途：存储超级管理员设置的全局操作密码（bcrypt 哈希值）
// 过期时间：永久存储（无 TTL）
func RedisSystemOperationPasswordKey() string {
	return "system:operation_password"
}

// ========================================
// 支付配置缓存 Redis Key
// ========================================

// RedisPaymentConfigKey 支付配置缓存 Key
// 用途：缓存 WechatConfig 数据（JSON 格式），避免每次支付时重复查询数据库
// 格式：payment:config:{configID}
// TTL：1 小时
func RedisPaymentConfigKey(configID uint) string {
	return fmt.Sprintf("payment:config:%d", configID)
}

// RedisWeComAccessTokenKey 返回企业微信应用 access_token 缓存 Key。
func RedisWeComAccessTokenKey(applicationID uint) string {
	return fmt.Sprintf("wecom:application:%d:access_token", applicationID)
}

// RedisWeComAccessTokenLockKey 返回企业微信应用 access_token 回源短锁 Key。
func RedisWeComAccessTokenLockKey(applicationID uint) string {
	return fmt.Sprintf("wecom:application:%d:access_token:lock", applicationID)
}
