using System.Text.Json;
using HoneyBox.Admin.Business.Models;
using HoneyBox.Admin.Business.Models.Config;
using HoneyBox.Admin.Business.Services.Interfaces;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Admin.Business.Services;

/// <summary>
/// 后台配置服务实现
/// </summary>
public class AdminConfigService : IAdminConfigService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly IRedisService _redisService;
    private readonly ILogger<AdminConfigService> _logger;

    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true,
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = false
    };

    public AdminConfigService(
        HoneyBoxDbContext dbContext,
        IRedisService redisService,
        ILogger<AdminConfigService> logger)
    {
        _dbContext = dbContext;
        _redisService = redisService;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task<T?> GetConfigAsync<T>(string key) where T : class
    {
        var jsonValue = await GetConfigRawAsync(key);
        if (string.IsNullOrEmpty(jsonValue))
        {
            return null;
        }

        try
        {
            return JsonSerializer.Deserialize<T>(jsonValue, JsonOptions);
        }
        catch (JsonException ex)
        {
            _logger.LogWarning(ex, "Failed to deserialize config {Key}", key);
            return null;
        }
    }

    /// <inheritdoc />
    public async Task<string?> GetConfigRawAsync(string key)
    {
        // 尝试从缓存获取
        var cacheKey = GetCacheKey(key);
        try
        {
            var cachedValue = await _redisService.GetStringAsync(cacheKey);
            if (!string.IsNullOrEmpty(cachedValue))
            {
                return cachedValue;
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to get config from cache: {Key}", key);
        }

        // 从数据库获取
        var config = await _dbContext.Configs
            .Where(c => c.ConfigKey == key)
            .Select(c => c.ConfigValue)
            .FirstOrDefaultAsync();

        // 存入缓存（10分钟过期）
        if (!string.IsNullOrEmpty(config))
        {
            try
            {
                await _redisService.SetStringAsync(cacheKey, config, TimeSpan.FromMinutes(10));
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Failed to cache config: {Key}", key);
            }
        }

        return config;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateConfigAsync<T>(string key, T config) where T : class
    {
        var jsonValue = JsonSerializer.Serialize(config, JsonOptions);
        return await UpdateConfigRawAsync(key, jsonValue);
    }

    /// <inheritdoc />
    public async Task<bool> UpdateConfigRawAsync(string key, string jsonValue)
    {
        // 验证配置
        var validationError = await ValidateConfigAsync(key, jsonValue);
        if (!string.IsNullOrEmpty(validationError))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, validationError);
        }

        // 查找现有配置
        var existingConfig = await _dbContext.Configs
            .FirstOrDefaultAsync(c => c.ConfigKey == key);

        if (existingConfig != null)
        {
            // 如果值相同，直接返回成功（无需更新）
            if (existingConfig.ConfigValue == jsonValue)
            {
                return true;
            }
            // 更新现有配置
            existingConfig.ConfigValue = jsonValue;
        }
        else
        {
            // 创建新配置
            var newConfig = new Config
            {
                ConfigKey = key,
                ConfigValue = jsonValue
            };
            _dbContext.Configs.Add(newConfig);
        }

        var result = await _dbContext.SaveChangesAsync() > 0;

        // 清理缓存
        if (result)
        {
            await ClearConfigCacheAsync(key);
        }

        return result;
    }


    /// <inheritdoc />
    public Task<string?> ValidateConfigAsync(string key, string jsonValue)
    {
        try
        {
            // 验证JSON格式
            using var doc = JsonDocument.Parse(jsonValue);

            // 根据配置键进行特定验证
            return key switch
            {
                ConfigKeys.WeixinPaySetting => Task.FromResult(ValidateWeixinPaySetting(jsonValue)),
                ConfigKeys.AlipayPaySetting => Task.FromResult(ValidateAlipaySetting(jsonValue)),
                ConfigKeys.MiniprogramSetting => Task.FromResult(ValidateMiniprogramSetting(jsonValue)),
                ConfigKeys.H5Setting => Task.FromResult(ValidateH5Setting(jsonValue)),
                _ => Task.FromResult<string?>(null)
            };
        }
        catch (JsonException)
        {
            return Task.FromResult<string?>("配置格式无效，请提供有效的JSON数据");
        }
    }

    /// <inheritdoc />
    public async Task ClearConfigCacheAsync(string key)
    {
        var cacheKey = GetCacheKey(key);
        try
        {
            await _redisService.DeleteAsync(cacheKey);
            _logger.LogInformation("Cleared config cache: {Key}", key);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to clear config cache: {Key}", key);
        }
    }

    /// <inheritdoc />
    public async Task<int> ClearAllPosterCacheAsync()
    {
        try
        {
            // 删除所有海报缓存记录
            var count = await _dbContext.Database.ExecuteSqlRawAsync("DELETE FROM user_poster_cache");
            _logger.LogInformation("Cleared {Count} poster cache records", count);
            return count;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to clear poster cache");
            throw;
        }
    }

    #region Private Validation Methods

    /// <summary>
    /// 验证支付宝配置
    /// </summary>
    private string? ValidateAlipaySetting(string jsonValue)
    {
        try
        {
            var setting = JsonSerializer.Deserialize<AlipaySetting>(jsonValue, JsonOptions);
            if (setting?.Merchants == null || setting.Merchants.Count == 0)
            {
                return null; // 空配置是允许的
            }

            foreach (var merchant in setting.Merchants)
            {
                // 验证AppId必填
                if (string.IsNullOrWhiteSpace(merchant.AppId))
                {
                    return $"商户\"{merchant.Name}\"的AppId不能为空";
                }

                // 验证商户名称必填
                if (string.IsNullOrWhiteSpace(merchant.Name))
                {
                    return "商户名称不能为空";
                }
            }

            return null;
        }
        catch (JsonException)
        {
            return "支付宝配置格式无效";
        }
    }

    /// <summary>
    /// 验证微信支付配置
    /// </summary>
    private string? ValidateWeixinPaySetting(string jsonValue)
    {
        try
        {
            var setting = JsonSerializer.Deserialize<WeixinPaySetting>(jsonValue, JsonOptions);
            if (setting?.Merchants == null || setting.Merchants.Count == 0)
            {
                return null; // 空配置是允许的
            }

            var prefixes = new HashSet<string>();
            foreach (var merchant in setting.Merchants)
            {
                // 验证前缀长度
                if (string.IsNullOrEmpty(merchant.OrderPrefix) || merchant.OrderPrefix.Length != 3)
                {
                    return $"商户\"{merchant.Name}\"的前缀必须是3位字符";
                }

                // 验证前缀唯一性
                if (!prefixes.Add(merchant.OrderPrefix))
                {
                    return $"商户前缀\"{merchant.OrderPrefix}\"重复，每个商户的前缀必须唯一";
                }
            }

            return null;
        }
        catch (JsonException)
        {
            return "微信支付配置格式无效";
        }
    }


    /// <summary>
    /// 验证小程序配置
    /// </summary>
    private string? ValidateMiniprogramSetting(string jsonValue)
    {
        try
        {
            var setting = JsonSerializer.Deserialize<MiniprogramSetting>(jsonValue, JsonOptions);
            if (setting?.Miniprograms == null || setting.Miniprograms.Count == 0)
            {
                return null; // 空配置是允许的
            }

            var hasDefault = false;
            var prefixes = new HashSet<string>();

            foreach (var miniprogram in setting.Miniprograms)
            {
                // 检查是否有默认小程序
                if (miniprogram.IsDefault == 1)
                {
                    hasDefault = true;
                }

                // 验证订单前缀（如果有）
                if (!string.IsNullOrEmpty(miniprogram.OrderPrefix))
                {
                    if (miniprogram.OrderPrefix.Length != 2)
                    {
                        return $"小程序\"{miniprogram.Name}\"的订单前缀必须是2位字符";
                    }

                    if (!prefixes.Add(miniprogram.OrderPrefix))
                    {
                        return $"订单前缀\"{miniprogram.OrderPrefix}\"重复，每个小程序的前缀必须唯一";
                    }
                }
            }

            if (!hasDefault)
            {
                return "请至少设置一个默认小程序";
            }

            return null;
        }
        catch (JsonException)
        {
            return "小程序配置格式无效";
        }
    }

    /// <summary>
    /// 验证H5配置
    /// </summary>
    private string? ValidateH5Setting(string jsonValue)
    {
        try
        {
            var setting = JsonSerializer.Deserialize<H5Setting>(jsonValue, JsonOptions);
            if (setting?.H5Apps == null || setting.H5Apps.Count == 0)
            {
                return null; // 空配置是允许的
            }

            var hasDefault = false;
            var prefixes = new HashSet<string>();

            foreach (var h5app in setting.H5Apps)
            {
                // 检查是否有默认H5应用
                if (h5app.IsDefault == 1)
                {
                    hasDefault = true;
                }

                // 验证订单前缀（如果有）
                if (!string.IsNullOrEmpty(h5app.OrderPrefix))
                {
                    if (h5app.OrderPrefix.Length != 2)
                    {
                        return $"H5应用\"{h5app.Name}\"的订单前缀必须是2位字符";
                    }

                    if (!prefixes.Add(h5app.OrderPrefix))
                    {
                        return $"订单前缀\"{h5app.OrderPrefix}\"重复，每个H5应用的前缀必须唯一";
                    }
                }
            }

            if (!hasDefault)
            {
                return "请至少设置一个默认H5应用";
            }

            return null;
        }
        catch (JsonException)
        {
            return "H5配置格式无效";
        }
    }

    #endregion

    #region Private Helper Methods

    private static string GetCacheKey(string key) => $"config:{key}";

    #endregion
}
