using System.ComponentModel.DataAnnotations;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.Identity.Commands;
using TakeoutSaaS.Application.Identity.Contracts;
using TakeoutSaaS.Application.Identity.Queries;
using TakeoutSaaS.Module.Authorization.Attributes;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;

namespace TakeoutSaaS.AdminApi.Controllers;

/// <summary>
/// 权限管理。
/// </summary>
[ApiVersion("1.0")]
[Authorize]
[Route("api/admin/v{version:apiVersion}/permissions")]
public sealed class PermissionsController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 分页查询权限。
    /// </summary>
    /// <remarks>
    /// 示例：GET /api/admin/v1/permissions?keyword=order&amp;page=1&amp;pageSize=20
    /// </remarks>
    /// <param name="query">查询条件。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>权限的分页结果。</returns>
    [HttpGet]
    [PermissionAuthorize("identity:permission:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PermissionDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<PermissionDto>>> Search([FromQuery] SearchPermissionsQuery query, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(query, cancellationToken);
        return ApiResponse<PagedResult<PermissionDto>>.Ok(result);
    }

    /// <summary>
    /// 获取权限树。
    /// </summary>
    /// <param name="keyword">关键字（可选）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>权限树列表。</returns>
    [HttpGet("tree")]
    [PermissionAuthorize("identity:permission:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<PermissionTreeDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<PermissionTreeDto>>> Tree([FromQuery] string? keyword, CancellationToken cancellationToken)
    {
        // 1. 构造查询对象
        var query = new PermissionTreeQuery { Keyword = keyword };

        // 2. 查询权限树
        var result = await mediator.Send(query, cancellationToken);

        // 3. 返回结果
        return ApiResponse<IReadOnlyList<PermissionTreeDto>>.Ok(result);
    }

    /// <summary>
    /// 创建权限。
    /// </summary>
    /// <param name="command">创建命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建的权限。</returns>
    [HttpPost]
    [PermissionAuthorize("identity:permission:create")]
    [ProducesResponseType(typeof(ApiResponse<PermissionDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PermissionDto>> Create([FromBody, Required] CreatePermissionCommand command, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(command, cancellationToken);
        return ApiResponse<PermissionDto>.Ok(result);
    }

    /// <summary>
    /// 更新权限。
    /// </summary>
    /// <param name="permissionId">权限 ID。</param>
    /// <param name="command">更新命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新后的权限，未找到时返回 404。</returns>
    [HttpPut("{permissionId:long}")]
    [PermissionAuthorize("identity:permission:update")]
    [ProducesResponseType(typeof(ApiResponse<PermissionDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PermissionDto>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<PermissionDto>> Update(long permissionId, [FromBody, Required] UpdatePermissionCommand command, CancellationToken cancellationToken)
    {
        command = command with { PermissionId = permissionId };
        var result = await mediator.Send(command, cancellationToken);
        return result is null
            ? ApiResponse<PermissionDto>.Error(StatusCodes.Status404NotFound, "权限不存在")
            : ApiResponse<PermissionDto>.Ok(result);
    }

    /// <summary>
    /// 删除权限。
    /// </summary>
    /// <param name="permissionId">权限 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>删除结果。</returns>
    [HttpDelete("{permissionId:long}")]
    [PermissionAuthorize("identity:permission:delete")]
    [ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<bool>> Delete(long permissionId, CancellationToken cancellationToken)
    {
        var command = new DeletePermissionCommand { PermissionId = permissionId };
        var result = await mediator.Send(command, cancellationToken);
        return ApiResponse<bool>.Ok(result);
    }
}
