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

namespace HoneyBox.Core.Services;

/// <summary>
/// 推荐服务实现
/// </summary>
public class InvitationService : IInvitationService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly IPosterService _posterService;
    private readonly ILogger<InvitationService> _logger;
    private const int PageSize = 15;

    public InvitationService(
        HoneyBoxDbContext dbContext,
        IPosterService posterService,
        ILogger<InvitationService> logger)
    {
        _dbContext = dbContext;
        _posterService = posterService;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task<InvitationInfoResponse> GetInvitationInfoAsync(int userId, int page, string? platform = null)
    {
        // 获取被邀请用户列表（pid = userId 且 status = 1）
        var query = _dbContext.Users
            .Where(u => u.Pid == userId && u.Status == 1)
            .OrderByDescending(u => u.Id);

        // 获取总数
        var totalCount = await query.CountAsync();

        // 计算分页
        var totalPages = (int)Math.Ceiling((double)totalCount / PageSize);
        var skip = (page - 1) * PageSize;

        // 获取当前页数据
        var invitedUsers = await query
            .Skip(skip)
            .Take(PageSize)
            .Select(u => new
            {
                u.Id,
                u.Nickname,
                u.HeadImg,
                u.Pid,
                u.CreatedAt
            })
            .ToListAsync();

        // 计算每个被邀请用户带来的佣金
        var invitationRecords = new List<InvitationRecordDto>();
        foreach (var user in invitedUsers)
        {
            var commissionMoney = await CalculateCommissionMoneyAsync(userId, user.Id);
            invitationRecords.Add(new InvitationRecordDto
            {
                Id = user.Id,
                Nickname = user.Nickname,
                Headimg = user.HeadImg,
                Pid = user.Pid,
                Addtime = user.CreatedAt.ToString("yyyy-MM-dd HH:mm:ss"),
                CommissionMoney = commissionMoney
            });
        }

        // 计算总奖励金额
        var totalMoney = await CalculateTotalRewardAsync(userId);

        // 获取分享配置
        var shareTitle = await GetShareTitleAsync();
        
        // 生成用户专属海报
        var shareImage = string.Empty;
        _logger.LogInformation("开始为用户 {UserId} 生成海报，平台: {Platform}", userId, platform);
        var posterResult = await _posterService.GetUserPosterAsync(userId, platform);
        if (posterResult.Success && !string.IsNullOrEmpty(posterResult.ImageUrl))
        {
            shareImage = posterResult.ImageUrl;
            _logger.LogInformation("用户 {UserId} 海报生成成功: {Url}", userId, shareImage);
        }
        else
        {
            // 如果海报生成失败，使用静态分享图片作为备选
            shareImage = await GetShareImageAsync();
            _logger.LogWarning("用户 {UserId} 海报生成失败: {Message}，平台: {Platform}，使用静态分享图片: {FallbackImage}", 
                userId, posterResult.Message, platform, shareImage);
        }

        return new InvitationInfoResponse
        {
            ShareTitle = shareTitle,
            ShareImage = shareImage,
            Count = totalCount,
            Money = totalMoney,
            Data = invitationRecords,
            LastPage = totalPages
        };
    }

    /// <inheritdoc />
    public async Task<BindInviteCodeResponse> BindInviteCodeAsync(int userId, string inviteCode)
    {
        // 获取当前用户
        var user = await _dbContext.Users.FindAsync(userId);
        if (user == null)
        {
            return new BindInviteCodeResponse
            {
                Success = false,
                Message = "用户不存在"
            };
        }

        // 检查是否已绑定推荐人
        if (user.Pid > 0)
        {
            return new BindInviteCodeResponse
            {
                Success = false,
                Message = "您已绑定过邀请码"
            };
        }

        // 检查是否在注册24小时内
        var registerTime = user.CreatedAt;
        var deadline = registerTime.AddHours(24);
        if (DateTime.Now > deadline)
        {
            return new BindInviteCodeResponse
            {
                Success = false,
                Message = "新用户注册24小时内才可以绑定邀请码"
            };
        }

        // 检查是否绑定自己
        if (user.Uid == inviteCode)
        {
            return new BindInviteCodeResponse
            {
                Success = false,
                Message = "不能绑定自己"
            };
        }

        // 查找邀请人
        var inviter = await _dbContext.Users
            .FirstOrDefaultAsync(u => u.Uid == inviteCode);

        if (inviter == null)
        {
            return new BindInviteCodeResponse
            {
                Success = false,
                Message = "邀请码不存在"
            };
        }

        // 绑定邀请码
        user.Pid = inviter.Id;
        user.UpdatedAt = DateTime.Now;
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("用户 {UserId} 成功绑定邀请码 {InviteCode}，推荐人ID: {InviterId}",
            userId, inviteCode, inviter.Id);

        return new BindInviteCodeResponse
        {
            Success = true,
            Message = "绑定成功"
        };
    }

    #region 私有方法

    /// <summary>
    /// 计算某个被邀请用户带来的佣金
    /// 佣金来源：type=5 的 ProfitMoney 和 ProfitIntegral 记录
    /// </summary>
    /// <param name="inviterId">邀请人ID</param>
    /// <param name="invitedUserId">被邀请用户ID</param>
    /// <returns>佣金金额</returns>
    private async Task<decimal> CalculateCommissionMoneyAsync(int inviterId, int invitedUserId)
    {
        // 从 ProfitMoney 获取佣金（type=5, share_uid=被邀请用户ID, change_money>0）
        var moneyCommission = await _dbContext.ProfitMoneys
            .Where(p => p.UserId == inviterId)
            .Where(p => p.Type == 5)
            .Where(p => p.ShareUid == invitedUserId)
            .Where(p => p.ChangeMoney > 0)
            .SumAsync(p => p.ChangeMoney);

        // 从 ProfitIntegral 获取佣金（type=5, share_uid=被邀请用户ID, change_money>0）
        var integralCommission = await _dbContext.ProfitIntegrals
            .Where(p => p.UserId == inviterId)
            .Where(p => p.Type == 5)
            .Where(p => p.ShareUid == invitedUserId)
            .Where(p => p.ChangeMoney > 0)
            .SumAsync(p => p.ChangeMoney);

        // 积分转换为金额（除以100）
        if (integralCommission > 0)
        {
            moneyCommission += Math.Round(integralCommission / 100, 2);
        }

        return moneyCommission;
    }

    /// <summary>
    /// 计算用户的总推荐奖励金额
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>总奖励金额</returns>
    private async Task<decimal> CalculateTotalRewardAsync(int userId)
    {
        // 从 ProfitMoney 获取总佣金（type=5, change_money>0）
        var moneyReward = await _dbContext.ProfitMoneys
            .Where(p => p.UserId == userId)
            .Where(p => p.Type == 5)
            .Where(p => p.ChangeMoney > 0)
            .SumAsync(p => p.ChangeMoney);

        // 从 ProfitIntegral 获取总佣金（type=5, change_money>0）
        var integralReward = await _dbContext.ProfitIntegrals
            .Where(p => p.UserId == userId)
            .Where(p => p.Type == 5)
            .Where(p => p.ChangeMoney > 0)
            .SumAsync(p => p.ChangeMoney);

        // 积分转换为金额（除以100）
        if (integralReward > 0)
        {
            moneyReward += Math.Round(integralReward / 100, 2);
        }

        return moneyReward;
    }

    /// <summary>
    /// 获取分享标题配置
    /// </summary>
    /// <returns>分享标题</returns>
    private async Task<string> GetShareTitleAsync()
    {
        var config = await _dbContext.Configs
            .FirstOrDefaultAsync(c => c.ConfigKey == "base");

        if (config?.ConfigValue == null)
        {
            return string.Empty;
        }

        try
        {
            var jsonDoc = JsonSerializer.Deserialize<JsonElement>(config.ConfigValue);
            if (jsonDoc.TryGetProperty("share_title", out var shareTitle))
            {
                return shareTitle.GetString() ?? string.Empty;
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "解析分享配置失败");
        }

        return string.Empty;
    }

    /// <summary>
    /// 获取分享海报图片配置
    /// </summary>
    /// <returns>分享海报图片URL</returns>
    private async Task<string> GetShareImageAsync()
    {
        var config = await _dbContext.Configs
            .FirstOrDefaultAsync(c => c.ConfigKey == "base");

        if (config?.ConfigValue == null)
        {
            return string.Empty;
        }

        try
        {
            var jsonDoc = JsonSerializer.Deserialize<JsonElement>(config.ConfigValue);
            if (jsonDoc.TryGetProperty("share_image", out var shareImage))
            {
                return shareImage.GetString() ?? string.Empty;
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "解析分享海报图片配置失败");
        }

        return string.Empty;
    }

    #endregion
}
