using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MissionService.API.Application.Commands;
using MissionService.API.Application.Queries;

namespace MissionService.API.Controllers;

/// <summary>
/// EN: Controller for daily check-in operations
/// VI: Controller cho các thao tác điểm danh hàng ngày
/// </summary>
[ApiController]
[Route("api/v1/[controller]")]
[Authorize]
public class CheckInsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<CheckInsController> _logger;

    public CheckInsController(IMediator mediator, ILogger<CheckInsController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// EN: Perform daily check-in / VI: Thực hiện điểm danh hàng ngày
    /// </summary>
    [HttpPost]
    [ProducesResponseType(typeof(CheckInResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> CheckIn()
    {
        var userId = GetCurrentUserId();
        var result = await _mediator.Send(new PerformCheckInCommand(userId));

        if (!result.Success)
        {
            return BadRequest(result);
        }

        return Ok(result);
    }

    /// <summary>
    /// EN: Get current check-in status / VI: Lấy trạng thái check-in hiện tại
    /// </summary>
    [HttpGet("status")]
    [ProducesResponseType(typeof(CheckInStatusResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetStatus()
    {
        var userId = GetCurrentUserId();
        var result = await _mediator.Send(new GetCheckInStatusQuery(userId));
        return Ok(result);
    }

    /// <summary>
    /// EN: Get check-in history for a specific month / VI: Lấy lịch sử check-in cho tháng cụ thể
    /// </summary>
    [HttpGet("history")]
    [ProducesResponseType(typeof(CheckInHistoryResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetHistory([FromQuery] int? year, [FromQuery] int? month)
    {
        var userId = GetCurrentUserId();
        var now = DateTime.UtcNow;
        var result = await _mediator.Send(new GetCheckInHistoryQuery(
            userId,
            year ?? now.Year,
            month ?? now.Month));
        return Ok(result);
    }

    /// <summary>
    /// EN: Get check-in streak leaderboard / VI: Lấy bảng xếp hạng streak check-in
    /// </summary>
    [HttpGet("leaderboard")]
    [AllowAnonymous]
    [ProducesResponseType(typeof(CheckInLeaderboardResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetLeaderboard([FromQuery] int count = 10)
    {
        var result = await _mediator.Send(new GetCheckInLeaderboardQuery(Math.Min(count, 100)));
        return Ok(result);
    }

    /// <summary>
    /// EN: Get streak bonus configuration / VI: Lấy cấu hình thưởng streak
    /// </summary>
    [HttpGet("config")]
    [AllowAnonymous]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public IActionResult GetStreakConfig()
    {
        // EN: Return streak bonus tiers for client display
        // VI: Trả về các cấp thưởng streak cho client hiển thị
        var config = new
        {
            Tiers = new[]
            {
                new { Days = "1-6", DailyPoints = 2, MilestoneBonus = 0 },
                new { Days = "7", DailyPoints = 3, MilestoneBonus = 20 },
                new { Days = "8-13", DailyPoints = 3, MilestoneBonus = 0 },
                new { Days = "14", DailyPoints = 4, MilestoneBonus = 35 },
                new { Days = "15-20", DailyPoints = 4, MilestoneBonus = 0 },
                new { Days = "21", DailyPoints = 5, MilestoneBonus = 50 },
                new { Days = "22-29", DailyPoints = 5, MilestoneBonus = 0 },
                new { Days = "30+", DailyPoints = 10, MilestoneBonus = 100 }
            },
            Currency = "MP"
        };

        return Ok(config);
    }

    private Guid GetCurrentUserId()
    {
        // EN: Extract user ID from JWT claims / VI: Trích xuất user ID từ JWT claims
        var userIdClaim = User.FindFirst("sub") ?? User.FindFirst("user_id");
        if (userIdClaim != null && Guid.TryParse(userIdClaim.Value, out var userId))
        {
            return userId;
        }

        throw new UnauthorizedAccessException("User ID not found in token");
    }
}
