using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using TakeoutSaaS.Application.App.Tenants.Commands;
using TakeoutSaaS.Application.App.Tenants.Dto;
using TakeoutSaaS.Application.App.Tenants.Queries;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;

namespace TakeoutSaaS.AdminApi.Controllers;

/// <summary>
/// 应用端公告（面向已认证用户）。
/// </summary>
[ApiVersion("1.0")]
[Authorize]
[Route("api/app/announcements")]
public sealed class AppAnnouncementsController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 获取当前用户可见的公告列表（已发布/有效期内）。
    /// </summary>
    /// <remarks>
    /// 示例：
    /// <code>
    /// GET /api/app/announcements?page=1&amp;pageSize=20
    /// Header: Authorization: Bearer &lt;JWT&gt;
    /// 响应:
    /// {
    ///   "success": true,
    ///   "code": 200,
    ///   "data": {
    ///     "items": [],
    ///     "page": 1,
    ///     "pageSize": 20,
    ///     "totalCount": 0
    ///   }
    /// }
    /// </code>
    /// </remarks>
    [HttpGet]
    [SwaggerOperation(Summary = "获取可见公告列表", Description = "仅返回已发布且在有效期内的公告（含平台公告）。")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<TenantAnnouncementDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<PagedResult<TenantAnnouncementDto>>> List([FromQuery] GetTenantsAnnouncementsQuery query, CancellationToken cancellationToken)
    {
        var request = query with
        {
            Status = AnnouncementStatus.Published,
            IsActive = true,
            OnlyEffective = true
        };

        var result = await mediator.Send(request, cancellationToken);
        return ApiResponse<PagedResult<TenantAnnouncementDto>>.Ok(result);
    }

    /// <summary>
    /// 获取当前用户未读公告。
    /// </summary>
    /// <remarks>
    /// 示例：
    /// <code>
    /// GET /api/app/announcements/unread?page=1&amp;pageSize=20
    /// 响应:
    /// {
    ///   "success": true,
    ///   "code": 200,
    ///   "data": {
    ///     "items": [],
    ///     "page": 1,
    ///     "pageSize": 20,
    ///     "totalCount": 0
    ///   }
    /// }
    /// </code>
    /// </remarks>
    [HttpGet("unread")]
    [SwaggerOperation(Summary = "获取未读公告", Description = "仅返回未读且在有效期内的已发布公告。")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<TenantAnnouncementDto>>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<PagedResult<TenantAnnouncementDto>>> GetUnread([FromQuery] GetUnreadAnnouncementsQuery query, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(query, cancellationToken);
        return ApiResponse<PagedResult<TenantAnnouncementDto>>.Ok(result);
    }

    /// <summary>
    /// 标记公告已读。
    /// </summary>
    /// <remarks>
    /// 示例：
    /// <code>
    /// POST /api/app/announcements/900123456789012345/mark-read
    /// 响应:
    /// {
    ///   "success": true,
    ///   "code": 200,
    ///   "data": {
    ///     "id": "900123456789012345",
    ///     "isRead": true
    ///   }
    /// }
    /// </code>
    /// </remarks>
    [HttpPost("{announcementId:long}/mark-read")]
    [SwaggerOperation(Summary = "标记公告已读", Description = "仅已发布且可见的公告允许标记已读。")]
    [ProducesResponseType(typeof(ApiResponse<TenantAnnouncementDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<TenantAnnouncementDto>> MarkRead(long announcementId, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(new MarkAnnouncementAsReadCommand { AnnouncementId = announcementId }, cancellationToken);
        return result is null
            ? ApiResponse<TenantAnnouncementDto>.Error(StatusCodes.Status404NotFound, "公告不存在")
            : ApiResponse<TenantAnnouncementDto>.Ok(result);
    }
}
