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

namespace HoneyBox.Core.Services;

/// <summary>
/// 配置服务实现
/// </summary>
public class ConfigService : IConfigService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<ConfigService> _logger;
    private readonly IRedisService _redisService;

    // 当前版本号
    private const string CurrentVersion = "116";

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

    /// <inheritdoc />
    public async Task<ConfigResponseDto> GetConfigAsync()
    {
        var response = new ConfigResponseDto
        {
            Version = CurrentVersion
        };

        // 1. 获取商品类型列表
        var goodsTypes = await _dbContext.GoodsTypes
            .OrderBy(g => g.SortOrder)
            .Select(g => new GoodsTypeDto
            {
                Value = g.Value,
                SortOrder = g.SortOrder,
                IsShow = g.IsShow,
                Name = g.Name,
                PayWechat = g.PayWechat,
                PayBalance = g.PayBalance,
                PayCurrency = g.PayCurrency,
                PayCurrency2 = g.PayCurrency2,
                PayCoupon = g.PayCoupon,
                IsDeduction = g.IsDeduction
            })
            .ToListAsync();

        response.GoodType = goodsTypes;

        // 2. 获取应用设置
        var appSettingJson = await GetConfigValueAsync("app_setting");
        if (!string.IsNullOrEmpty(appSettingJson))
        {
            try
            {
                response.AppSetting = JsonSerializer.Deserialize<AppSettingDto>(appSettingJson, 
                    new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Failed to deserialize app_setting config");
            }
        }

        // 3. 获取基础配置
        var baseConfigJson = await GetConfigValueAsync("base");
        if (!string.IsNullOrEmpty(baseConfigJson))
        {
            try
            {
                var baseConfig = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(baseConfigJson,
                    new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
                
                if (baseConfig != null)
                {
                    response.BaseConfig = new BaseConfigDto
                    {
                        IsShouTan = GetIntValue(baseConfig, "is_shou_tan"),
                        JumpAppid = GetStringValue(baseConfig, "jump_appid"),
                        Corpid = GetStringValue(baseConfig, "corpid"),
                        WxLink = GetStringValue(baseConfig, "wx_link"),
                        Erweima = GetStringValue(baseConfig, "erweima"),
                        ShareImage = GetStringValue(baseConfig, "share_image"),
                        ShareTitle = GetStringValue(baseConfig, "share_title")
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Failed to deserialize base config");
            }
        }

        return response;
    }

    /// <inheritdoc />
    public Task<PlatformConfigDto> GetPlatformConfigAsync(string? platform)
    {
        // 根据平台返回不同配置
        // isWebPay = false 表示直接拉起微信支付，true 表示走客服消息支付
        var config = new PlatformConfigDto
        {
            IsWebPay = false  // 默认关闭 Web 支付，使用原生微信支付
        };

        // 可以根据 platform 参数返回不同配置
        // 例如: MP-WEIXIN, WEB_H5, APP_ANDROID 等
        // 目前所有平台都使用原生支付

        return Task.FromResult(config);
    }

    /// <inheritdoc />
    public async Task<string?> GetConfigValueAsync(string key)
    {
        // 尝试从缓存获取
        var cacheKey = $"config:{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<List<AdvertDto>> GetAdvertListAsync(int typeId)
    {
        var adverts = await _dbContext.Adverts
            .Where(a => a.Type == typeId)
            .OrderByDescending(a => a.Sort)
            .ThenByDescending(a => a.Id)
            .Select(a => new AdvertDto
            {
                ImgUrl = a.ImgUrl,
                Ttype = a.Ttype,
                CouponId = a.CouponId,
                GoodsId = a.GoodsId,
                Url = a.Url
            })
            .ToListAsync();

        // 处理图片URL（如果需要补全路径）
        foreach (var advert in adverts)
        {
            advert.ImgUrl = FormatImageUrl(advert.ImgUrl);
        }

        return adverts;
    }

    /// <inheritdoc />
    public async Task<DanyeDto?> GetDanyeAsync(int type)
    {
        var danye = await _dbContext.Danyes
            .Where(d => d.Id == type)
            .FirstOrDefaultAsync();

        if (danye == null)
        {
            return null;
        }

        return new DanyeDto
        {
            Content = FormatContentUrl(danye.Content),
            Title = danye.Title,
            IsImageOptimizer = danye.IsImageOptimizer
        };
    }

    /// <inheritdoc />
    public async Task<DanyeContentDto?> GetDanyeContentAsync(int type, string? platform)
    {
        // 平台适配：APP平台下，type 4/5 映射到 30/31
        var actualType = type;
        if (!string.IsNullOrEmpty(platform))
        {
            var upperPlatform = platform.ToUpper();
            if (upperPlatform == "APP_ANDROID" || upperPlatform == "APP_IOS")
            {
                if (type == 4)
                {
                    actualType = 30;
                }
                else if (type == 5)
                {
                    actualType = 31;
                }
            }
        }

        var danye = await _dbContext.Danyes
            .Where(d => d.Id == actualType)
            .FirstOrDefaultAsync();

        if (danye == null)
        {
            return new DanyeContentDto
            {
                Content = string.Empty,
                IsImageOptimizer = 0
            };
        }

        return new DanyeContentDto
        {
            Content = FormatContentUrl(danye.Content),
            IsImageOptimizer = danye.IsImageOptimizer
        };
    }

    #region Private Helper Methods

    private static int GetIntValue(Dictionary<string, JsonElement> dict, string key)
    {
        if (dict.TryGetValue(key, out var element))
        {
            if (element.ValueKind == JsonValueKind.Number)
            {
                return element.GetInt32();
            }
            if (element.ValueKind == JsonValueKind.String && int.TryParse(element.GetString(), out var value))
            {
                return value;
            }
        }
        return 0;
    }

    private static string? GetStringValue(Dictionary<string, JsonElement> dict, string key)
    {
        if (dict.TryGetValue(key, out var element))
        {
            if (element.ValueKind == JsonValueKind.String)
            {
                return element.GetString();
            }
            if (element.ValueKind != JsonValueKind.Null)
            {
                return element.ToString();
            }
        }
        return null;
    }

    /// <summary>
    /// 格式化图片URL
    /// </summary>
    private static string FormatImageUrl(string? imgUrl)
    {
        if (string.IsNullOrEmpty(imgUrl))
        {
            return string.Empty;
        }

        // 如果已经是完整URL，直接返回
        if (imgUrl.StartsWith("http://") || imgUrl.StartsWith("https://"))
        {
            return imgUrl;
        }

        // 否则直接返回（可以从配置读取基础URL进行拼接）
        return imgUrl;
    }

    /// <summary>
    /// 格式化富文本内容中的URL（处理图片等资源路径）
    /// </summary>
    private static string FormatContentUrl(string? content)
    {
        if (string.IsNullOrEmpty(content))
        {
            return string.Empty;
        }

        // 富文本内容中的图片URL处理
        // PHP中的contentUrl函数会处理相对路径，这里保持一致
        return content;
    }

    #endregion
}
