using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using StorageService.API.Application.Commands.Admin;
using StorageService.API.Application.Queries.Admin;
using Swashbuckle.AspNetCore.Annotations;
using System.Security.Claims;
using Asp.Versioning;

namespace StorageService.API.Controllers.Admin;

/// <summary>
/// EN: Admin controller for file share management.
/// VI: Controller admin cho quản lý chia sẻ files.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/admin/shares")]
[Authorize(Roles = "Admin,SuperAdmin")]
[SwaggerTag("Admin Share Management - View and manage file shares")]
public class AdminSharesController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<AdminSharesController> _logger;

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

    /// <summary>
    /// EN: Get all file shares with pagination.
    /// VI: Lấy tất cả file shares với phân trang.
    /// </summary>
    [HttpGet]
    [SwaggerOperation(Summary = "Get all shares", Description = "Get all file shares with filtering")]
    [SwaggerResponse(200, "Shares retrieved successfully")]
    [SwaggerResponse(403, "Forbidden - Admin role required")]
    public async Task<ActionResult<ApiResponse<AdminSharesResult>>> GetAll(
        [FromQuery] int pageNumber = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] string? status = null,
        [FromQuery] string? sharedBy = null,
        CancellationToken cancellationToken = default)
    {
        var query = new AdminGetSharesQuery(pageNumber, pageSize, status, sharedBy);
        var result = await _mediator.Send(query, cancellationToken);

        return Ok(new ApiResponse<AdminSharesResult> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Revoke a file share (admin action).
    /// VI: Thu hồi chia sẻ file (hành động admin).
    /// </summary>
    [HttpDelete("{shareId:guid}")]
    [SwaggerOperation(Summary = "Revoke share", Description = "Revoke a file share as admin")]
    [SwaggerResponse(200, "Share revoked successfully")]
    [SwaggerResponse(404, "Share not found")]
    public async Task<ActionResult<ApiResponse<AdminRevokeShareResult>>> Revoke(
        Guid shareId,
        [FromBody] AdminRevokeRequest request,
        CancellationToken cancellationToken = default)
    {
        var adminUserId = GetUserId();
        if (string.IsNullOrEmpty(adminUserId))
            return Unauthorized(new ApiResponse<AdminRevokeShareResult> { Success = false, Error = "Admin ID not found" });

        _logger.LogWarning("Admin {AdminId} revoking share {ShareId} for reason: {Reason}", adminUserId, shareId, request.Reason);

        var command = new AdminRevokeShareCommand(shareId, adminUserId, request.Reason);
        var result = await _mediator.Send(command, cancellationToken);

        if (!result.Success)
            return NotFound(new ApiResponse<AdminRevokeShareResult> { Success = false, Error = result.Error });

        return Ok(new ApiResponse<AdminRevokeShareResult> { Success = true, Data = result });
    }

    private string? GetUserId() => User.FindFirstValue(ClaimTypes.NameIdentifier);
}

/// <summary>
/// EN: Request model for admin revoke action.
/// VI: Request model cho hành động thu hồi bởi admin.
/// </summary>
public record AdminRevokeRequest(string Reason);
