using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using TakeoutSaaS.Application.App.QuotaPackages.Commands;
using TakeoutSaaS.Application.App.QuotaPackages.Dto;
using TakeoutSaaS.Application.App.QuotaPackages.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}/quota-packages")]
public sealed class QuotaPackagesController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 配额包列表。
    /// </summary>
    /// <param name="query">查询条件。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>配额包分页结果。</returns>
    [HttpGet]
    [PermissionAuthorize("quota-package:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<QuotaPackageListDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<QuotaPackageListDto>>> List([FromQuery] GetQuotaPackageListQuery query, CancellationToken cancellationToken)
    {
        // 1. 查询配额包分页
        var result = await mediator.Send(query, cancellationToken);

        // 2. 返回结果
        return ApiResponse<PagedResult<QuotaPackageListDto>>.Ok(result);
    }

    /// <summary>
    /// 创建配额包。
    /// </summary>
    /// <param name="command">创建命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建后的配额包。</returns>
    [HttpPost]
    [PermissionAuthorize("quota-package:create")]
    [ProducesResponseType(typeof(ApiResponse<QuotaPackageDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<QuotaPackageDto>> Create([FromBody, Required] CreateQuotaPackageCommand command, CancellationToken cancellationToken)
    {
        // 1. 执行创建
        var result = await mediator.Send(command, cancellationToken);

        // 2. 返回创建结果
        return ApiResponse<QuotaPackageDto>.Ok(result);
    }

    /// <summary>
    /// 更新配额包。
    /// </summary>
    /// <param name="quotaPackageId">配额包 ID。</param>
    /// <param name="command">更新命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新后的配额包或未找到。</returns>
    [HttpPut("{quotaPackageId:long}")]
    [PermissionAuthorize("quota-package:update")]
    [ProducesResponseType(typeof(ApiResponse<QuotaPackageDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<QuotaPackageDto>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<QuotaPackageDto>> Update(long quotaPackageId, [FromBody, Required] UpdateQuotaPackageCommand command, CancellationToken cancellationToken)
    {
        // 1. 绑定路由 ID
        command = command with { QuotaPackageId = quotaPackageId };

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

        // 3. 返回更新结果或 404
        return result is null
            ? ApiResponse<QuotaPackageDto>.Error(StatusCodes.Status404NotFound, "配额包不存在")
            : ApiResponse<QuotaPackageDto>.Ok(result);
    }

    /// <summary>
    /// 删除配额包。
    /// </summary>
    /// <param name="quotaPackageId">配额包 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>删除结果。</returns>
    [HttpDelete("{quotaPackageId:long}")]
    [PermissionAuthorize("quota-package:delete")]
    [ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<bool>> Delete(long quotaPackageId, CancellationToken cancellationToken)
    {
        // 1. 构建删除命令
        var command = new DeleteQuotaPackageCommand { QuotaPackageId = quotaPackageId };

        // 2. 执行删除并返回
        var result = await mediator.Send(command, cancellationToken);
        return ApiResponse<bool>.Ok(result);
    }

    /// <summary>
    /// 上架/下架配额包。
    /// </summary>
    /// <param name="quotaPackageId">配额包 ID。</param>
    /// <param name="command">状态更新命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新结果。</returns>
    [HttpPut("{quotaPackageId:long}/status")]
    [PermissionAuthorize("quota-package:update")]
    [ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<bool>> UpdateStatus(long quotaPackageId, [FromBody, Required] UpdateQuotaPackageStatusCommand command, CancellationToken cancellationToken)
    {
        // 1. 绑定路由 ID
        command = command with { QuotaPackageId = quotaPackageId };

        // 2. 执行状态更新
        var result = await mediator.Send(command, cancellationToken);

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

    /// <summary>
    /// 为租户购买配额包。
    /// </summary>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="command">购买命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>购买记录。</returns>
    [HttpPost("~/api/admin/v{version:apiVersion}/tenants/{tenantId:long}/quota-packages")]
    [PermissionAuthorize("tenant:quota:purchase")]
    [ProducesResponseType(typeof(ApiResponse<TenantQuotaPurchaseDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<TenantQuotaPurchaseDto>> PurchaseForTenant(
        long tenantId,
        [FromBody, Required] PurchaseQuotaPackageCommand command,
        CancellationToken cancellationToken)
    {
        // 1. 绑定租户 ID
        command = command with { TenantId = tenantId };

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

        // 3. 返回购买结果
        return ApiResponse<TenantQuotaPurchaseDto>.Ok(result);
    }

    /// <summary>
    /// 租户配额使用情况。
    /// </summary>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="query">查询条件。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>配额使用情况列表。</returns>
    [HttpGet("~/api/admin/v{version:apiVersion}/tenants/{tenantId:long}/quota-usage")]
    [PermissionAuthorize("tenant:quota:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<TenantQuotaUsageDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<TenantQuotaUsageDto>>> GetTenantQuotaUsage(
        long tenantId,
        [FromQuery] GetTenantQuotaUsageQuery query,
        CancellationToken cancellationToken)
    {
        // 1. 绑定租户 ID
        query = query with { TenantId = tenantId };

        // 2. 查询配额使用情况
        var result = await mediator.Send(query, cancellationToken);

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

    /// <summary>
    /// 租户配额购买记录。
    /// </summary>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="query">查询条件。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>购买记录分页结果。</returns>
    [HttpGet("~/api/admin/v{version:apiVersion}/tenants/{tenantId:long}/quota-purchases")]
    [PermissionAuthorize("tenant:quota:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<TenantQuotaPurchaseDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<TenantQuotaPurchaseDto>>> GetTenantQuotaPurchases(
        long tenantId,
        [FromQuery] GetTenantQuotaPurchasesQuery query,
        CancellationToken cancellationToken)
    {
        // 1. 绑定租户 ID
        query = query with { TenantId = tenantId };

        // 2. 查询购买记录
        var result = await mediator.Send(query, cancellationToken);

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