using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.Identity.Abstractions;
using TakeoutSaaS.Application.Identity.Contracts;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;
using TakeoutSaaS.Shared.Web.Security;

namespace TakeoutSaaS.TenantApi.Controllers;

/// <summary>
/// 租户管理端登录认证。
/// </summary>
/// <remarks>提供登录、刷新 Token、获取用户信息及菜单等能力。</remarks>
[ApiVersion("1.0")]
[Authorize]
[Route("api/tenant/v{version:apiVersion}/auth")]
public sealed class AuthController(IAdminAuthService authService) : BaseApiController
{
    /// <summary>
    /// 账号密码登录。
    /// </summary>
    /// <param name="request">登录请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>访问令牌与刷新令牌。</returns>
    [HttpPost("login")]
    [AllowAnonymous]
    [ProducesResponseType(typeof(ApiResponse<TokenResponse>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<TokenResponse>> Login([FromBody] AdminLoginRequest request, CancellationToken cancellationToken)
    {
        // 1. 调用认证服务登录
        var response = await authService.LoginAsync(request, cancellationToken);

        // 2. 返回令牌
        return ApiResponse<TokenResponse>.Ok(response);
    }

    /// <summary>
    /// 刷新 Token。
    /// </summary>
    /// <param name="request">刷新令牌请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>新的访问令牌与刷新令牌。</returns>
    [HttpPost("refresh")]
    [AllowAnonymous]
    [ProducesResponseType(typeof(ApiResponse<TokenResponse>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<TokenResponse>> RefreshToken([FromBody] RefreshTokenRequest request, CancellationToken cancellationToken)
    {
        // 1. 刷新 Token
        var response = await authService.RefreshTokenAsync(request, cancellationToken);

        // 2. 返回新的令牌
        return ApiResponse<TokenResponse>.Ok(response);
    }

    /// <summary>
    /// 获取当前用户信息。
    /// </summary>
    /// <remarks>
    /// 示例响应:
    /// <code>
    /// {
    ///   "success": true,
    ///   "code": 200,
    ///   "data": {
    ///     "userId": "900123456789012345",
    ///     "account": "admin",
    ///     "displayName": "租户管理员",
    ///     "tenantId": "100000000000000001",
    ///     "packageName": "标准版",
    ///     "roles": ["tenant-admin"],
    ///     "permissions": ["identity:profile:read", "merchant:read"]
    ///   }
    /// }
    /// </code>
    /// </remarks>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>当前用户档案信息。</returns>
    [HttpGet("profile")]
    [ProducesResponseType(typeof(ApiResponse<CurrentUserProfile>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<CurrentUserProfile>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<CurrentUserProfile>> GetProfile(CancellationToken cancellationToken)
    {
        // 1. 从 JWT 中获取当前用户标识
        var userId = User.GetUserId();
        if (userId == 0)
        {
            return ApiResponse<CurrentUserProfile>.Error(ErrorCodes.Unauthorized, "Token 缺少有效的用户标识");
        }

        // 2. 读取用户档案并返回
        var profile = await authService.GetProfileAsync(userId, cancellationToken);
        return ApiResponse<CurrentUserProfile>.Ok(profile);
    }

    /// <summary>
    /// 获取当前用户的权限码列表。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>权限码数组。</returns>
    [HttpGet("permissions")]
    [ProducesResponseType(typeof(ApiResponse<string[]>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<string[]>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<string[]>> GetPermissions(CancellationToken cancellationToken)
    {
        // 1. 从 JWT 中获取当前用户标识
        var userId = User.GetUserId();
        if (userId == 0)
        {
            return ApiResponse<string[]>.Error(ErrorCodes.Unauthorized, "Token 缺少有效的用户标识");
        }

        // 2. 读取用户档案获取权限
        var profile = await authService.GetProfileAsync(userId, cancellationToken);
        return ApiResponse<string[]>.Ok(profile.Permissions);
    }

    /// <summary>
    /// 获取当前用户的菜单树（按权限过滤）。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>当前用户可见的菜单树。</returns>
    [HttpGet("menu")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<MenuNodeDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<MenuNodeDto>>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<IReadOnlyList<MenuNodeDto>>> GetMenuTree(CancellationToken cancellationToken)
    {
        // 1. 获取当前用户标识
        var userId = User.GetUserId();
        if (userId == 0)
        {
            return ApiResponse<IReadOnlyList<MenuNodeDto>>.Error(ErrorCodes.Unauthorized, "Token 缺少有效的用户标识");
        }

        // 2. 生成菜单树
        var menu = await authService.GetMenuTreeAsync(userId, cancellationToken);
        return ApiResponse<IReadOnlyList<MenuNodeDto>>.Ok(menu);
    }
}
