using HoneyBox.Core.Interfaces;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Core.Services;

/// <summary>
/// 商品缓存服务实现
/// </summary>
public class GoodsCacheService : IGoodsCacheService
{
    private readonly IRedisService _redisService;
    private readonly ILogger<GoodsCacheService> _logger;

    // 缓存键前缀 - 与PHP保持一致
    private const string JoinCountKeyPrefix = "order_goods_count:";
    private const string GoodsListKeyPrefix = "goods_list_";
    private const string GoodsDetailKeyPrefix = "goods_detail_";

    // 缓存过期时间
    private static readonly TimeSpan JoinCountExpiry = TimeSpan.FromMinutes(5);
    private static readonly TimeSpan GoodsListExpiry = TimeSpan.FromSeconds(30);
    private static readonly TimeSpan GoodsDetailExpiry = TimeSpan.FromMinutes(5);

    public GoodsCacheService(
        IRedisService redisService,
        ILogger<GoodsCacheService> logger)
    {
        _redisService = redisService;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task<int> GetJoinCountAsync(int goodsId)
    {
        var key = $"{JoinCountKeyPrefix}{goodsId}";
        var value = await _redisService.GetStringAsync(key);
        
        if (int.TryParse(value, out var count))
        {
            return count;
        }
        
        // 返回-1表示缓存不存在
        return -1;
    }

    /// <inheritdoc />
    public async Task SetJoinCountAsync(int goodsId, int count)
    {
        var key = $"{JoinCountKeyPrefix}{goodsId}";
        await _redisService.SetStringAsync(key, count.ToString(), JoinCountExpiry);
    }

    /// <inheritdoc />
    public async Task<int> IncrementJoinCountAsync(int goodsId)
    {
        var key = $"{JoinCountKeyPrefix}{goodsId}";
        var currentValue = await GetJoinCountAsync(goodsId);
        var newValue = currentValue > 0 ? currentValue + 1 : 1;
        
        await _redisService.SetStringAsync(key, newValue.ToString(), JoinCountExpiry);
        
        return newValue;
    }

    /// <inheritdoc />
    public async Task InvalidateGoodsCacheAsync(int goodsId)
    {
        // 清除参与次数缓存
        var joinCountKey = $"{JoinCountKeyPrefix}{goodsId}";
        await _redisService.DeleteAsync(joinCountKey);
        
        // 清除商品详情缓存 - 由于箱号可能有多个，这里清除所有可能的箱号缓存
        // 注意：实际生产环境中可能需要使用Redis的SCAN命令来批量删除
        // 这里简化处理，只清除常见的箱号范围（0-100）
        var deleteTasks = new List<Task>();
        for (int num = 0; num <= 100; num++)
        {
            var detailKey = $"{GoodsDetailKeyPrefix}{goodsId}_{num}";
            deleteTasks.Add(_redisService.DeleteAsync(detailKey));
        }
        await Task.WhenAll(deleteTasks);
        
        _logger.LogInformation("已清除商品 {GoodsId} 的所有缓存（参与次数、商品详情）", goodsId);
    }

    /// <inheritdoc />
    public async Task<string?> GetGoodsListCacheAsync(string cacheKey)
    {
        var key = $"{GoodsListKeyPrefix}{cacheKey}";
        return await _redisService.GetStringAsync(key);
    }

    /// <inheritdoc />
    public async Task SetGoodsListCacheAsync(string cacheKey, string data, TimeSpan expiry)
    {
        var key = $"{GoodsListKeyPrefix}{cacheKey}";
        await _redisService.SetStringAsync(key, data, expiry);
    }

    /// <inheritdoc />
    public async Task<string?> GetGoodsDetailCacheAsync(int goodsId, int goodsNum)
    {
        var key = $"{GoodsDetailKeyPrefix}{goodsId}_{goodsNum}";
        return await _redisService.GetStringAsync(key);
    }

    /// <inheritdoc />
    public async Task SetGoodsDetailCacheAsync(int goodsId, int goodsNum, string data, TimeSpan expiry)
    {
        var key = $"{GoodsDetailKeyPrefix}{goodsId}_{goodsNum}";
        await _redisService.SetStringAsync(key, data, expiry);
    }
}
