using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.Dictionary.Abstractions;
using TakeoutSaaS.Application.Dictionary.Contracts;
using TakeoutSaaS.Application.Dictionary.Models;
using TakeoutSaaS.Module.Authorization.Attributes;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;

namespace TakeoutSaaS.AdminApi.Controllers;

/// <summary>
/// 参数字典管理。
/// </summary>
/// <param name="dictionaryAppService">字典服务</param>
[ApiVersion("1.0")]
[Authorize]
[Route("api/admin/v{version:apiVersion}/dictionaries")]
public sealed class DictionaryController(IDictionaryAppService dictionaryAppService) : BaseApiController
{
    /// <summary>
    /// 查询字典分组。
    /// </summary>
    /// <param name="query">分组查询条件。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>分组列表。</returns>
    [HttpGet]
    [PermissionAuthorize("dictionary:group:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<DictionaryGroupDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<DictionaryGroupDto>>> GetGroups([FromQuery] DictionaryGroupQuery query, CancellationToken cancellationToken)
    {
        // 1. 查询字典分组
        var groups = await dictionaryAppService.SearchGroupsAsync(query, cancellationToken);

        // 2. 返回分组列表
        return ApiResponse<IReadOnlyList<DictionaryGroupDto>>.Ok(groups);
    }

    /// <summary>
    /// 创建字典分组。
    /// </summary>
    /// <param name="request">创建分组请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建后的分组。</returns>
    [HttpPost]
    [PermissionAuthorize("dictionary:group:create")]
    [ProducesResponseType(typeof(ApiResponse<DictionaryGroupDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<DictionaryGroupDto>> CreateGroup([FromBody] CreateDictionaryGroupRequest request, CancellationToken cancellationToken)
    {
        // 1. 创建字典分组
        var group = await dictionaryAppService.CreateGroupAsync(request, cancellationToken);

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

    /// <summary>
    /// 更新字典分组。
    /// </summary>
    /// <param name="groupId">分组 ID。</param>
    /// <param name="request">更新请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新后的分组。</returns>
    [HttpPut("{groupId:long}")]
    [PermissionAuthorize("dictionary:group:update")]
    [ProducesResponseType(typeof(ApiResponse<DictionaryGroupDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<DictionaryGroupDto>> UpdateGroup(long groupId, [FromBody] UpdateDictionaryGroupRequest request, CancellationToken cancellationToken)
    {
        // 1. 更新字典分组
        var group = await dictionaryAppService.UpdateGroupAsync(groupId, request, cancellationToken);

        // 2. 返回更新结果
        return ApiResponse<DictionaryGroupDto>.Ok(group);
    }

    /// <summary>
    /// 删除字典分组。
    /// </summary>
    /// <param name="groupId">分组 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>操作结果。</returns>
    [HttpDelete("{groupId:long}")]
    [PermissionAuthorize("dictionary:group:delete")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<object>> DeleteGroup(long groupId, CancellationToken cancellationToken)
    {
        // 1. 删除字典分组
        await dictionaryAppService.DeleteGroupAsync(groupId, cancellationToken);

        // 2. 返回成功响应
        return ApiResponse.Success();
    }

    /// <summary>
    /// 创建字典项。
    /// </summary>
    /// <param name="groupId">分组 ID。</param>
    /// <param name="request">创建请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建的字典项。</returns>
    [HttpPost("{groupId:long}/items")]
    [PermissionAuthorize("dictionary:item:create")]
    [ProducesResponseType(typeof(ApiResponse<DictionaryItemDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<DictionaryItemDto>> CreateItem(long groupId, [FromBody] CreateDictionaryItemRequest request, CancellationToken cancellationToken)
    {
        // 1. 绑定分组标识
        request.GroupId = groupId;

        // 2. 创建字典项
        var item = await dictionaryAppService.CreateItemAsync(request, cancellationToken);
        return ApiResponse<DictionaryItemDto>.Ok(item);
    }

    /// <summary>
    /// 更新字典项。
    /// </summary>
    /// <param name="itemId">字典项 ID。</param>
    /// <param name="request">更新请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新后的字典项。</returns>
    [HttpPut("items/{itemId:long}")]
    [PermissionAuthorize("dictionary:item:update")]
    [ProducesResponseType(typeof(ApiResponse<DictionaryItemDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<DictionaryItemDto>> UpdateItem(long itemId, [FromBody] UpdateDictionaryItemRequest request, CancellationToken cancellationToken)
    {
        // 1. 更新字典项
        var item = await dictionaryAppService.UpdateItemAsync(itemId, request, cancellationToken);

        // 2. 返回更新结果
        return ApiResponse<DictionaryItemDto>.Ok(item);
    }

    /// <summary>
    /// 删除字典项。
    /// </summary>
    /// <param name="itemId">字典项 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>操作结果。</returns>
    [HttpDelete("items/{itemId:long}")]
    [PermissionAuthorize("dictionary:item:delete")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<object>> DeleteItem(long itemId, CancellationToken cancellationToken)
    {
        // 1. 删除字典项
        await dictionaryAppService.DeleteItemAsync(itemId, cancellationToken);

        // 2. 返回成功响应
        return ApiResponse.Success();
    }

    /// <summary>
    /// 批量获取字典项（命中缓存）。
    /// </summary>
    /// <param name="request">批量查询请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>分组编码到字典项列表的映射。</returns>
    [HttpPost("batch")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyDictionary<string, IReadOnlyList<DictionaryItemDto>>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyDictionary<string, IReadOnlyList<DictionaryItemDto>>>> BatchGet([FromBody] DictionaryBatchQueryRequest request, CancellationToken cancellationToken)
    {
        // 1. 批量读取并命中缓存
        var dictionaries = await dictionaryAppService.GetCachedItemsAsync(request, cancellationToken);

        // 2. 返回批量结果
        return ApiResponse<IReadOnlyDictionary<string, IReadOnlyList<DictionaryItemDto>>>.Ok(dictionaries);
    }
}
