using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.App.Billings.Commands;
using TakeoutSaaS.Application.App.Billings.Contracts;
using TakeoutSaaS.Application.App.Billings.Queries;
using TakeoutSaaS.Domain.Billings.Enums;
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}/billings")]
public sealed class BillingsController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 获取账单列表（分页）。
    /// </summary>
    /// <param name="TenantId">租户 ID。</param>
    /// <param name="Status">账单状态。</param>
    /// <param name="BillingType">账单类型。</param>
    /// <param name="StartDate">开始日期。</param>
    /// <param name="EndDate">结束日期。</param>
    /// <param name="MinAmount">最小金额。</param>
    /// <param name="MaxAmount">最大金额。</param>
    /// <param name="Keyword">关键词（账单号、租户名）。</param>
    /// <param name="SortBy">排序字段。</param>
    /// <param name="SortDesc">是否降序。</param>
    /// <param name="PageNumber">页码（从 1 开始）。</param>
    /// <param name="PageSize">每页条数。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>账单分页列表。</returns>
    [HttpGet]
    [PermissionAuthorize("tenant:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<BillingListDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<BillingListDto>>> List(
        [FromQuery] long? TenantId,
        [FromQuery] TenantBillingStatus? Status,
        [FromQuery] TenantBillingType? BillingType,
        [FromQuery] DateTime? StartDate,
        [FromQuery] DateTime? EndDate,
        [FromQuery] decimal? MinAmount,
        [FromQuery] decimal? MaxAmount,
        [FromQuery] string? Keyword,
        [FromQuery] string? SortBy,
        [FromQuery] bool? SortDesc,
        [FromQuery] int PageNumber = 1,
        [FromQuery] int PageSize = 10,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造查询
        var query = new ListBillingsQuery
        {
            TenantId = TenantId,
            Status = Status,
            BillingType = BillingType,
            StartDate = StartDate,
            EndDate = EndDate,
            MinAmount = MinAmount,
            MaxAmount = MaxAmount,
            Keyword = Keyword,
            SortBy = SortBy,
            SortDesc = SortDesc,
            PageNumber = PageNumber,
            PageSize = PageSize
        };

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

        // 3. 返回账单分页列表
        return ApiResponse<PagedResult<BillingListDto>>.Ok(result);
    }

    /// <summary>
    /// 获取账单详情。
    /// </summary>
    /// <param name="id">账单 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>账单详情。</returns>
    [HttpGet("{id:long}")]
    [PermissionAuthorize("tenant:read")]
    [ProducesResponseType(typeof(ApiResponse<BillingDetailDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<BillingDetailDto>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<BillingDetailDto>> GetDetail(
        [FromRoute] long id,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造查询
        var query = new GetBillingDetailQuery { BillingId = id };

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

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

        // 4. 返回账单详情
        return ApiResponse<BillingDetailDto>.Ok(result);
    }

    /// <summary>
    /// 一键确认收款（记录支付 + 立即审核通过 + 同步更新账单状态）。
    /// </summary>
    /// <param name="id">账单 ID。</param>
    /// <param name="command">确认收款命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>支付记录。</returns>
    [HttpPost("{id:long}/payments/confirm")]
    [PermissionAuthorize("tenant:read")]
    [ProducesResponseType(typeof(ApiResponse<PaymentRecordDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PaymentRecordDto>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<PaymentRecordDto>> ConfirmPayment(
        [FromRoute] long id,
        [FromBody] ConfirmPaymentCommand command,
        CancellationToken cancellationToken = default)
    {
        // 1. 构造命令（使用路由中的 ID）
        var cmd = command with { BillingId = id };

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

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

        // 4. 返回支付记录
        return ApiResponse<PaymentRecordDto>.Ok(result);
    }
}
