using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;

namespace QYZH.InteractiveMagazine.Service;

/// <summary>
/// 社区微信端服务实现
/// </summary>
public class WeChatCommunityService(
    BaseRepository<CommunityMessage> messageRepository,
    ILogger<WeChatCommunityService> logger)
    : BaseRepository<CommunityMessage>, IWeChatCommunityService
{
    private const int FeaturedCount = 5;
    private const int NormalCount = 5;

    /// <summary>
    /// 获取社区Feed流（翻页）
    /// </summary>
    public async Task<WxFeedOutput> GetFeedAsync(long userId, long? cursor)
    {
        logger.LogInformation("正在获取社区Feed，用户ID: {UserId}, Cursor: {Cursor}", userId, cursor);

        var journalIds = await GetUserJournalIds(userId);
        if (!journalIds.Any())
        {
            return new WxFeedOutput { Messages = new List<WxFeedMessageOutput>(), HasMore = false };
        }

        // 查询精选消息
        var featuredQuery = messageRepository.Queryable()
            .Where(m => journalIds.Contains(m.JournalId)
                        && m.Status == 1
                        && m.IsActive
                        && m.UserId != userId
                        && m.IsFeatured == 1);

        // 查询普通消息
        var normalQuery = messageRepository.Queryable()
            .Where(m => journalIds.Contains(m.JournalId)
                        && m.Status == 1
                        && m.IsActive
                        && m.UserId != userId
                        && m.IsFeatured == 0);

        // 游标分页：按ID降序（ID越大越新）
        if (cursor.HasValue)
        {
            featuredQuery = featuredQuery.Where(m => m.Id < cursor.Value);
            normalQuery = normalQuery.Where(m => m.Id < cursor.Value);
        }

        var featured = await featuredQuery
            .OrderByDescending(m => m.SortOrder)
            .Take(FeaturedCount)
            .ToListAsync();

        var normal = await normalQuery
            .OrderByDescending(m => m.SortOrder)
            .Take(NormalCount)
            .ToListAsync();

        // 混排
        var mixed = MixMessages(featured, normal);

        // 查询当前用户点赞状态
        var messageIds = mixed.Select(m => m.Id).ToList();
        var likedIds = await GetLikedMessageIds(userId, messageIds);

        var output = mixed.Select(m => new WxFeedMessageOutput
        {
            Id = m.Id,
            JournalId = m.JournalId,
            UserId = m.UserId,
            Content = m.Content,
            ImageUrl = m.ImageUrl,
            Type = m.Type.ToString(),
            LikeCount = m.LikeCount,
            IsFeatured = m.IsFeatured,
            IsLiked = likedIds.Contains(m.Id),
            CreatedAt = m.CreatedAt
        }).ToList();

        var nextCursor = mixed.Any() ? mixed.Min(m => m.Id) : (long?)null;
        var hasMore = featured.Count >= FeaturedCount || normal.Count >= NormalCount;

        return new WxFeedOutput
        {
            Messages = output,
            NextCursor = hasMore ? nextCursor : null,
            HasMore = hasMore
        };
    }

    /// <summary>
    /// 下拉刷新（重置游标，返回最新列表）
    /// </summary>
    public async Task<WxFeedOutput> RefreshFeedAsync(long userId)
    {
        logger.LogInformation("正在刷新社区Feed，用户ID: {UserId}", userId);
        return await GetFeedAsync(userId, null);
    }

    /// <summary>
    /// 点赞
    /// </summary>
    public async Task<WxLikeOutput> LikeAsync(long userId, WxLikeInput input)
    {
        logger.LogInformation("用户正在点赞，用户ID: {UserId}, 消息ID: {MessageId}", userId, input.MessageId);

        if (input.MessageId <= 0)
        {
            throw new BusinessException("消息ID无效", ResultCode.BAD_REQUEST);
        }

        var message = await messageRepository.GetByIdAsync(input.MessageId);
        if (message == null)
        {
            throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
        }

        // 检查是否已点赞
        var existingLike = await Context.Queryable<CommunityMessageLike>()
            .Where(l => l.UserId == userId && l.MessageId == input.MessageId && l.Type == CommunityMessageLikeTypeEnum.Like)
            .FirstAsync();

        if (existingLike != null)
        {
            throw new BusinessException("您已点赞过该消息", ResultCode.BAD_REQUEST);
        }

        // 插入点赞记录
        var like = new CommunityMessageLike
        {
            UserId = userId,
            MessageId = input.MessageId,
            Type = CommunityMessageLikeTypeEnum.Like,
            CreatedBy = "System",
            UpdatedBy = "System",
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now,
            IsDeleted = false
        };

        var insertResult = await Context.Insertable(like).ExecuteCommandAsync();
        if (insertResult <= 0)
        {
            throw new BusinessException("点赞失败", ResultCode.GLOBAL_ERROR);
        }

        // 更新点赞数
        await Context.Updateable<CommunityMessage>()
            .SetColumns(m => new CommunityMessage
            {
                LikeCount = m.LikeCount + 1,
                UpdatedAt = DateTime.Now
            })
            .Where(m => m.Id == input.MessageId)
            .ExecuteCommandAsync();

        logger.LogInformation("点赞成功，用户ID: {UserId}, 消息ID: {MessageId}", userId, input.MessageId);

        return new WxLikeOutput
        {
            MessageId = input.MessageId,
            LikeCount = message.LikeCount + 1,
            IsLiked = true
        };
    }

    /// <summary>
    /// 取消点赞
    /// </summary>
    public async Task<WxLikeOutput> UnlikeAsync(long userId, long messageId)
    {
        logger.LogInformation("用户正在取消点赞，用户ID: {UserId}, 消息ID: {MessageId}", userId, messageId);

        if (messageId <= 0)
        {
            throw new BusinessException("消息ID无效", ResultCode.BAD_REQUEST);
        }

        var message = await messageRepository.GetByIdAsync(messageId);
        if (message == null)
        {
            throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
        }

        var existingLike = await Context.Queryable<CommunityMessageLike>()
            .Where(l => l.UserId == userId && l.MessageId == messageId && l.Type == CommunityMessageLikeTypeEnum.Like)
            .FirstAsync();

        if (existingLike == null)
        {
            throw new BusinessException("您尚未点赞过该消息", ResultCode.BAD_REQUEST);
        }

        // 软删除点赞记录
        await Context.Updateable<CommunityMessageLike>()
            .SetColumns(l => new CommunityMessageLike { IsDeleted = true, UpdatedAt = DateTime.Now })
            .Where(l => l.Id == existingLike.Id)
            .ExecuteCommandAsync();

        // 更新点赞数（不小于0）
        var newLikeCount = Math.Max(0, message.LikeCount - 1);
        await Context.Updateable<CommunityMessage>()
            .SetColumns(m => new CommunityMessage
            {
                LikeCount = newLikeCount,
                UpdatedAt = DateTime.Now
            })
            .Where(m => m.Id == messageId)
            .ExecuteCommandAsync();

        logger.LogInformation("取消点赞成功，用户ID: {UserId}, 消息ID: {MessageId}", userId, messageId);

        return new WxLikeOutput
        {
            MessageId = messageId,
            LikeCount = newLikeCount,
            IsLiked = false
        };
    }

    #region 私有辅助方法

    /// <summary>
    /// 获取用户拥有的期刊ID列表
    /// </summary>
    private async Task<List<long>> GetUserJournalIds(long userId)
    {
        return await Context.Queryable<UserJournal>()
            .Where(uj => uj.UserId == userId && uj.Status == (int)UserJournalStatusEnum.Active)
            .Select(uj => uj.JournalId)
            .ToListAsync();
    }

    /// <summary>
    /// 获取当前用户已点赞的消息ID集合
    /// </summary>
    private async Task<HashSet<long>> GetLikedMessageIds(long userId, List<long> messageIds)
    {
        if (!messageIds.Any()) return new HashSet<long>();

        var likes = await Context.Queryable<CommunityMessageLike>()
            .Where(l => l.UserId == userId && messageIds.Contains(l.MessageId) && l.Type == CommunityMessageLikeTypeEnum.Like && !l.IsDeleted)
            .Select(l => l.MessageId)
            .ToListAsync();

        return likes.ToHashSet();
    }

    /// <summary>
    /// 混排精选消息和普通消息（按权重随机插入）
    /// </summary>
    private static List<CommunityMessage> MixMessages(List<CommunityMessage> featured, List<CommunityMessage> normal)
    {
        var result = new List<CommunityMessage>();
        var allMessages = new List<(CommunityMessage msg, bool isFeatured)>();

        allMessages.AddRange(featured.Select(m => (m, true)));
        allMessages.AddRange(normal.Select(m => (m, false)));

        // 按SortOrder加权随机排序：SortOrder越大出现越靠前
        var random = new Random();
        while (allMessages.Any())
        {
            var totalWeight = allMessages.Sum(x => Math.Max(1, x.msg.SortOrder));
            var pick = random.Next(0, totalWeight + 1);
            var cumulative = 0;
            var selectedIndex = 0;

            for (var i = 0; i < allMessages.Count; i++)
            {
                cumulative += Math.Max(1, allMessages[i].msg.SortOrder);
                if (pick <= cumulative)
                {
                    selectedIndex = i;
                    break;
                }
            }

            result.Add(allMessages[selectedIndex].msg);
            allMessages.RemoveAt(selectedIndex);
        }

        return result;
    }

    #endregion
}
