using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.App.TenantPackages.Commands;
using TakeoutSaaS.Application.App.TenantPackages.Contracts;
using TakeoutSaaS.Application.App.TenantPackages.Queries;
using TakeoutSaaS.Module.Authorization.Attributes;
using TakeoutSaaS.Shared.Abstractions.Constants;
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}/tenant-packages")]
public sealed class TenantPackagesController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 获取租户套餐列表（分页）。
    /// </summary>
    /// <param name="Keyword">关键字（套餐名称）。</param>
    /// <param name="IsActive">是否启用。</param>
    /// <param name="Page">页码（从 1 开始）。</param>
    /// <param name="PageSize">每页条数。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐分页列表。</returns>
    [HttpGet]
    [PermissionAuthorize("tenant-package:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<TenantPackageListDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<TenantPackageListDto>>> List(
        [FromQuery] string? Keyword,
        [FromQuery] bool? IsActive,
        [FromQuery] int Page = 1,
        [FromQuery] int PageSize = 10,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造查询
        var query = new ListTenantPackagesQuery
        {
            Keyword = Keyword,
            IsActive = IsActive,
            Page = Page,
            PageSize = PageSize
        };

        // 2. 执行查询
        var result = await mediator.Send(query, cancellationToken);

        // 3. 返回套餐分页列表
        return ApiResponse<PagedResult<TenantPackageListDto>>.Ok(result);
    }

    /// <summary>
    /// 获取租户套餐详情。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐详情。</returns>
    [HttpGet("{tenantPackageId:long}")]
    [PermissionAuthorize("tenant-package:read")]
    [ProducesResponseType(typeof(ApiResponse<TenantPackageListDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<TenantPackageListDto>> GetDetail(
        [FromRoute] long tenantPackageId,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造查询
        var query = new GetTenantPackageDetailQuery
        {
            TenantPackageId = tenantPackageId
        };

        // 2. 执行查询
        var result = await mediator.Send(query, cancellationToken);

        // 3. 如果不存在，返回 404
        if (result is null)
        {
            return ApiResponse<TenantPackageListDto>.Error(ErrorCodes.NotFound, "套餐不存在");
        }

        // 4. 返回套餐详情
        return ApiResponse<TenantPackageListDto>.Ok(result);
    }

    /// <summary>
    /// 获取租户套餐使用统计。
    /// </summary>
    /// <param name="tenantPackageIds">套餐 ID 列表。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐使用统计列表。</returns>
    [HttpGet("usages")]
    [PermissionAuthorize("tenant-package:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<TenantPackageUsageDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<TenantPackageUsageDto>>> GetUsages(
        [FromQuery] long[] tenantPackageIds,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造查询
        var query = new GetTenantPackageUsagesQuery
        {
            TenantPackageIds = tenantPackageIds
        };

        // 2. 执行查询
        var result = await mediator.Send(query, cancellationToken);

        // 3. 返回套餐使用统计
        return ApiResponse<IReadOnlyList<TenantPackageUsageDto>>.Ok(result);
    }

    /// <summary>
    /// 创建租户套餐。
    /// </summary>
    /// <param name="command">创建命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建的套餐。</returns>
    [HttpPost]
    [PermissionAuthorize("tenant-package:create")]
    [ProducesResponseType(typeof(ApiResponse<TenantPackageListDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<TenantPackageListDto>> Create(
        [FromBody] CreateTenantPackageCommand command,
        CancellationToken cancellationToken = default)
    {
        // 1. 执行命令
        var result = await mediator.Send(command, cancellationToken);

        // 2. 返回创建的套餐
        return ApiResponse<TenantPackageListDto>.Ok(result);
    }

    /// <summary>
    /// 更新租户套餐。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="command">更新命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新后的套餐。</returns>
    [HttpPut("{tenantPackageId:long}")]
    [PermissionAuthorize("tenant-package:update")]
    [ProducesResponseType(typeof(ApiResponse<TenantPackageListDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<TenantPackageListDto>> Update(
        [FromRoute] long tenantPackageId,
        [FromBody] UpdateTenantPackageCommand command,
        CancellationToken cancellationToken = default)
    {
        // 1. 确保路由 ID 与命令 ID 一致
        var updatedCommand = command with { TenantPackageId = tenantPackageId };

        // 2. 执行命令
        var result = await mediator.Send(updatedCommand, cancellationToken);

        // 3. 如果不存在，返回 404
        if (result is null)
        {
            return ApiResponse<TenantPackageListDto>.Error(ErrorCodes.NotFound, "套餐不存在");
        }

        // 4. 返回更新后的套餐
        return ApiResponse<TenantPackageListDto>.Ok(result);
    }

    /// <summary>
    /// 删除租户套餐（软删除）。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>是否删除成功。</returns>
    [HttpDelete("{tenantPackageId:long}")]
    [PermissionAuthorize("tenant-package:delete")]
    [ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<bool>> Delete(
        [FromRoute] long tenantPackageId,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造命令
        var command = new DeleteTenantPackageCommand
        {
            TenantPackageId = tenantPackageId
        };

        // 2. 执行命令
        var result = await mediator.Send(command, cancellationToken);

        // 3. 如果不存在，返回 404
        if (!result)
        {
            return ApiResponse<bool>.Error(ErrorCodes.NotFound, "套餐不存在");
        }

        // 4. 返回成功
        return ApiResponse<bool>.Ok(true);
    }

    /// <summary>
    /// 获取套餐当前使用租户列表（按有效订阅口径）。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="Keyword">关键字（租户名称或编码）。</param>
    /// <param name="ExpiringWithinDays">即将到期天数筛选。</param>
    /// <param name="Page">页码（从 1 开始）。</param>
    /// <param name="PageSize">每页条数。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>租户分页列表。</returns>
    [HttpGet("{tenantPackageId:long}/tenants")]
    [PermissionAuthorize("tenant-package:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<TenantPackageTenantDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<TenantPackageTenantDto>>> GetTenants(
        [FromRoute] long tenantPackageId,
        [FromQuery] string? Keyword,
        [FromQuery] int? ExpiringWithinDays,
        [FromQuery] int Page = 1,
        [FromQuery] int PageSize = 20,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造查询
        var query = new GetTenantPackageTenantsQuery
        {
            TenantPackageId = tenantPackageId,
            Keyword = Keyword,
            ExpiringWithinDays = ExpiringWithinDays,
            Page = Page,
            PageSize = PageSize
        };

        // 2. 执行查询
        var result = await mediator.Send(query, cancellationToken);

        // 3. 返回租户分页列表
        return ApiResponse<PagedResult<TenantPackageTenantDto>>.Ok(result);
    }
}
