using System.Security.Claims;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Base;
using HoneyBox.Model.Models.Rank;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace HoneyBox.Api.Controllers;

/// <summary>
/// 排行榜控制器 - 处理排行榜查询功能
/// </summary>
/// <remarks>
/// 提供周榜、月榜、通用排行榜等数据查询
/// </remarks>
[ApiController]
[Route("api")]
public class RankController : ControllerBase
{
    private readonly IRankService _rankService;
    private readonly ILogger<RankController> _logger;

    public RankController(
        IRankService rankService,
        ILogger<RankController> logger)
    {
        _rankService = rankService;
        _logger = logger;
    }

    /// <summary>
    /// 获取周榜
    /// </summary>
    /// <remarks>
    /// GET /api/rank_week
    /// 
    /// 获取本周消费排行榜数据
    /// Requirements: 10.1, 10.3-10.5
    /// </remarks>
    /// <returns>周榜数据</returns>
    [HttpGet("rank_week")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<RankResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<RankResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<RankResponse>> GetWeekRank()
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<RankResponse>.Unauthorized();
        }

        try
        {
            var result = await _rankService.GetWeekRankAsync(userId.Value);
            return ApiResponse<RankResponse>.Success(result);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Get week rank failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse<RankResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get week rank: UserId={UserId}", userId);
            return ApiResponse<RankResponse>.Fail("获取周榜失败");
        }
    }

    /// <summary>
    /// 获取月榜
    /// </summary>
    /// <remarks>
    /// GET /api/rank_month
    /// 
    /// 获取本月消费排行榜数据
    /// Requirements: 10.2-10.5
    /// </remarks>
    /// <returns>月榜数据</returns>
    [HttpGet("rank_month")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<RankResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<RankResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<RankResponse>> GetMonthRank()
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<RankResponse>.Unauthorized();
        }

        try
        {
            var result = await _rankService.GetMonthRankAsync(userId.Value);
            return ApiResponse<RankResponse>.Success(result);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Get month rank failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse<RankResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get month rank: UserId={UserId}", userId);
            return ApiResponse<RankResponse>.Fail("获取月榜失败");
        }
    }

    /// <summary>
    /// 获取通用排行榜列表
    /// </summary>
    /// <remarks>
    /// GET /api/getRankList?type=diamond&amp;page=1&amp;limit=10
    /// 
    /// 支持的排行榜类型:
    /// - diamond: 钻石排行榜
    /// - integral: UU币排行榜
    /// - dadajuan: 达达卷排行榜
    /// - invite: 邀请新人排行榜
    /// - loss: 亏损补贴排行榜
    /// 
    /// Requirements: 10.1, 10.2
    /// </remarks>
    /// <param name="type">排行榜类型</param>
    /// <param name="page">页码，默认1</param>
    /// <param name="limit">每页数量，默认10</param>
    /// <returns>排行榜数据列表</returns>
    [HttpGet("getRankList")]
    [ProducesResponseType(typeof(ApiResponse<List<GenericRankItemDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<List<GenericRankItemDto>>), StatusCodes.Status400BadRequest)]
    public async Task<ApiResponse<List<GenericRankItemDto>>> GetRankList(
        [FromQuery] string type,
        [FromQuery] int page = 1,
        [FromQuery] int limit = 10)
    {
        if (string.IsNullOrWhiteSpace(type))
        {
            return ApiResponse<List<GenericRankItemDto>>.Fail("排行榜类型不能为空");
        }

        try
        {
            var result = await _rankService.GetRankListAsync(type, page, limit);
            return ApiResponse<List<GenericRankItemDto>>.Success(result);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Get rank list failed: Type={Type}, Error={Error}", type, ex.Message);
            return ApiResponse<List<GenericRankItemDto>>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get rank list: Type={Type}", type);
            return ApiResponse<List<GenericRankItemDto>>.Fail("获取排行榜失败");
        }
    }

    /// <summary>
    /// 获取消费记录排行榜
    /// </summary>
    /// <remarks>
    /// GET /api/record?page=1
    /// 
    /// 获取本月消费记录排行榜数据
    /// Requirements: 10.1, 10.2
    /// </remarks>
    /// <param name="page">页码，默认1</param>
    /// <returns>消费记录排行榜数据</returns>
    [HttpGet("record")]
    [ProducesResponseType(typeof(ApiResponse<ConsumeRecordResponse>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<ConsumeRecordResponse>> GetConsumeRecord([FromQuery] int page = 1)
    {
        try
        {
            var result = await _rankService.GetConsumeRecordAsync(page, 10);
            return ApiResponse<ConsumeRecordResponse>.Success(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get consume record: Page={Page}", page);
            return ApiResponse<ConsumeRecordResponse>.Fail("获取消费记录排行榜失败");
        }
    }

    #region Private Helper Methods

    /// <summary>
    /// 获取当前登录用户ID
    /// </summary>
    private int? GetCurrentUserId()
    {
        var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
        if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId))
        {
            return null;
        }
        return userId;
    }

    #endregion
}
