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 management.
/// VI: Controller admin cho quản lý files.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/admin/files")]
[Authorize(Roles = "Admin,SuperAdmin")]
[SwaggerTag("Admin File Management - View and manage all user files")]
public class AdminFilesController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<AdminFilesController> _logger;

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

    /// <summary>
    /// EN: Get all files with pagination.
    /// VI: Lấy tất cả files với phân trang.
    /// </summary>
    [HttpGet]
    [SwaggerOperation(Summary = "Get all files", Description = "Get all files across all users with filtering")]
    [SwaggerResponse(200, "Files retrieved successfully")]
    [SwaggerResponse(403, "Forbidden - Admin role required")]
    public async Task<ActionResult<ApiResponse<AdminFilesResult>>> GetAll(
        [FromQuery] int pageNumber = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] string? userId = null,
        [FromQuery] string? accessLevel = null,
        [FromQuery] string? contentType = null,
        [FromQuery] DateTime? uploadedAfter = null,
        [FromQuery] DateTime? uploadedBefore = null,
        [FromQuery] string? sortBy = null,
        [FromQuery] bool descending = false,
        CancellationToken cancellationToken = default)
    {
        var query = new AdminGetFilesQuery(
            pageNumber, pageSize, userId, accessLevel, contentType,
            uploadedAfter, uploadedBefore, sortBy, descending);
        var result = await _mediator.Send(query, cancellationToken);

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

    /// <summary>
    /// EN: Delete a file (admin action).
    /// VI: Xóa file (hành động admin).
    /// </summary>
    [HttpDelete("{fileId:guid}")]
    [SwaggerOperation(Summary = "Delete file", Description = "Delete a file as admin (bypasses ownership check)")]
    [SwaggerResponse(200, "File deleted successfully")]
    [SwaggerResponse(404, "File not found")]
    public async Task<ActionResult<ApiResponse<AdminDeleteFileResult>>> Delete(
        Guid fileId,
        [FromBody] AdminDeleteRequest request,
        CancellationToken cancellationToken = default)
    {
        var adminUserId = GetUserId();
        if (string.IsNullOrEmpty(adminUserId))
            return Unauthorized(new ApiResponse<AdminDeleteFileResult> { Success = false, Error = "Admin ID not found" });

        _logger.LogWarning("Admin {AdminId} deleting file {FileId} for reason: {Reason}", adminUserId, fileId, request.Reason);

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

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

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

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

/// <summary>
/// EN: Request model for admin delete action.
/// VI: Request model cho hành động xóa bởi admin.
/// </summary>
public record AdminDeleteRequest(string Reason);
