using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MediatR;
using TakeoutSaaS.Application.App.Personal.Dto;
using TakeoutSaaS.Application.App.Personal.Queries;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;

namespace TakeoutSaaS.TenantApi.Controllers;

/// <summary>
/// 租户端个人中心。
/// </summary>
/// <remarks>
/// 提供个人总览、角色概览、配额、账单、支付、操作记录与消息摘要能力。
/// </remarks>
[ApiVersion("1.0")]
[Authorize]
[Produces("application/json")]
[Route("api/tenant/v{version:apiVersion}/personal")]
public sealed class PersonalController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 获取个人中心总览。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>总览结果。</returns>
    [HttpGet("overview")]
    [ProducesResponseType(typeof(ApiResponse<PersonalOverviewDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PersonalOverviewDto>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<PersonalOverviewDto>> GetOverview(CancellationToken cancellationToken)
    {
        // 1. 查询总览
        var overview = await mediator.Send(new GetPersonalOverviewQuery(), cancellationToken);

        // 2. 返回结果
        return ApiResponse<PersonalOverviewDto>.Ok(overview);
    }

    /// <summary>
    /// 获取我的角色与权限概览。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>角色权限概览。</returns>
    [HttpGet("roles")]
    [ProducesResponseType(typeof(ApiResponse<PersonalRolePermissionSummaryDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PersonalRolePermissionSummaryDto>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<PersonalRolePermissionSummaryDto>> GetRoles(CancellationToken cancellationToken)
    {
        // 1. 查询角色权限概览
        var summary = await mediator.Send(new GetPersonalRolesQuery(), cancellationToken);

        // 2. 返回结果
        return ApiResponse<PersonalRolePermissionSummaryDto>.Ok(summary);
    }

    /// <summary>
    /// 获取套餐与配额摘要。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>配额摘要。</returns>
    [HttpGet("quota")]
    [ProducesResponseType(typeof(ApiResponse<PersonalQuotaUsageSummaryDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PersonalQuotaUsageSummaryDto>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PersonalQuotaUsageSummaryDto>), StatusCodes.Status403Forbidden)]
    public async Task<ApiResponse<PersonalQuotaUsageSummaryDto>> GetQuota(CancellationToken cancellationToken)
    {
        // 1. 查询配额摘要
        var summary = await mediator.Send(new GetPersonalQuotaQuery(), cancellationToken);

        // 2. 返回结果
        return ApiResponse<PersonalQuotaUsageSummaryDto>.Ok(summary);
    }

    /// <summary>
    /// 分页查询账单记录。
    /// </summary>
    /// <param name="page">页码（从 1 开始）。</param>
    /// <param name="pageSize">每页条数。</param>
    /// <param name="from">开始时间（UTC）。</param>
    /// <param name="to">结束时间（UTC）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>账单分页结果。</returns>
    [HttpGet("billing/statements")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalBillingStatementDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalBillingStatementDto>>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalBillingStatementDto>>), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalBillingStatementDto>>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<PagedResult<PersonalBillingStatementDto>>> SearchBillingStatements(
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] DateTime? from = null,
        [FromQuery] DateTime? to = null,
        CancellationToken cancellationToken = default)
    {
        // 1. 发送查询
        var result = await mediator.Send(new SearchPersonalBillingStatementsQuery
        {
            Page = page,
            PageSize = pageSize,
            From = from,
            To = to
        }, cancellationToken);

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

    /// <summary>
    /// 分页查询支付记录。
    /// </summary>
    /// <param name="page">页码（从 1 开始）。</param>
    /// <param name="pageSize">每页条数。</param>
    /// <param name="from">开始时间（UTC）。</param>
    /// <param name="to">结束时间（UTC）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>支付记录分页结果。</returns>
    [HttpGet("billing/payments")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalPaymentRecordDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalPaymentRecordDto>>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalPaymentRecordDto>>), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalPaymentRecordDto>>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<PagedResult<PersonalPaymentRecordDto>>> SearchPayments(
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] DateTime? from = null,
        [FromQuery] DateTime? to = null,
        CancellationToken cancellationToken = default)
    {
        // 1. 发送查询
        var result = await mediator.Send(new SearchPersonalPaymentsQuery
        {
            Page = page,
            PageSize = pageSize,
            From = from,
            To = to
        }, cancellationToken);

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

    /// <summary>
    /// 获取账单/配额可见角色配置。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>可见角色配置。</returns>
    [HttpGet("visibility/roles")]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status403Forbidden)]
    public async Task<ApiResponse<PersonalVisibilityRoleConfigDto>> GetVisibilityRoles(CancellationToken cancellationToken)
    {
        // 1. 查询配置
        var config = await mediator.Send(new GetPersonalVisibilityRoleConfigQuery(), cancellationToken);

        // 2. 返回结果
        return ApiResponse<PersonalVisibilityRoleConfigDto>.Ok(config);
    }

    /// <summary>
    /// 更新账单/配额可见角色配置。
    /// </summary>
    /// <param name="command">更新请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新后的配置。</returns>
    [HttpPut("visibility/roles")]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ApiResponse<PersonalVisibilityRoleConfigDto>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<PersonalVisibilityRoleConfigDto>> UpdateVisibilityRoles(
        [FromBody] UpdatePersonalVisibilityRoleConfigCommand command,
        CancellationToken cancellationToken)
    {
        // 1. 更新配置
        var config = await mediator.Send(command, cancellationToken);

        // 2. 返回结果
        return ApiResponse<PersonalVisibilityRoleConfigDto>.Ok(config);
    }

    /// <summary>
    /// 分页查询个人操作记录。
    /// </summary>
    /// <param name="page">页码（从 1 开始）。</param>
    /// <param name="pageSize">每页条数（默认 50，最大 50）。</param>
    /// <param name="from">开始时间（UTC）。</param>
    /// <param name="to">结束时间（UTC）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>操作记录分页结果。</returns>
    [HttpGet("operations")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalOperationLogDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalOperationLogDto>>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalOperationLogDto>>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<PagedResult<PersonalOperationLogDto>>> SearchOperations(
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 50,
        [FromQuery] DateTime? from = null,
        [FromQuery] DateTime? to = null,
        CancellationToken cancellationToken = default)
    {
        // 1. 发送查询
        var result = await mediator.Send(new SearchPersonalOperationsQuery
        {
            Page = page,
            PageSize = pageSize,
            From = from,
            To = to
        }, cancellationToken);

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

    /// <summary>
    /// 分页查询个人消息摘要。
    /// </summary>
    /// <param name="page">页码（从 1 开始）。</param>
    /// <param name="pageSize">每页条数。</param>
    /// <param name="unreadOnly">是否仅返回未读。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>消息摘要分页结果。</returns>
    [HttpGet("notifications")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalNotificationDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalNotificationDto>>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<PersonalNotificationDto>>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<PagedResult<PersonalNotificationDto>>> SearchNotifications(
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] bool unreadOnly = false,
        CancellationToken cancellationToken = default)
    {
        // 1. 发送查询
        var result = await mediator.Send(new SearchPersonalNotificationsQuery
        {
            Page = page,
            PageSize = pageSize,
            UnreadOnly = unreadOnly
        }, cancellationToken);

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