using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.App.Products.Commands;
using TakeoutSaaS.Application.App.Products.Dto;
using TakeoutSaaS.Application.App.Products.Queries;
using TakeoutSaaS.Application.App.Stores.Services;
using TakeoutSaaS.Infrastructure.App.Persistence;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;
using TakeoutSaaS.TenantApi.Contracts.Product;

namespace TakeoutSaaS.TenantApi.Controllers;

/// <summary>
/// 租户端加料管理。
/// </summary>
[ApiVersion("1.0")]
[Authorize]
[Route("api/tenant/v{version:apiVersion}/product")]
public sealed class ProductAddonController(
    IMediator mediator,
    TakeoutAppDbContext dbContext,
    StoreContextService storeContextService) : BaseApiController
{
    /// <summary>
    /// 加料组列表。
    /// </summary>
    [HttpGet("addon/group/list")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<ProductAddonGroupItemResponse>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<ProductAddonGroupItemResponse>>> GetAddonGroupList(
        [FromQuery] ProductAddonGroupListRequest request,
        CancellationToken cancellationToken)
    {
        // 1. 校验门店访问权限。
        var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
        await EnsureStoreAccessibleAsync(storeId, cancellationToken);

        // 2. 查询并返回列表。
        var result = await mediator.Send(new GetProductAddonGroupListQuery
        {
            StoreId = storeId,
            Keyword = request.Keyword,
            Status = request.Status
        }, cancellationToken);

        return ApiResponse<IReadOnlyList<ProductAddonGroupItemResponse>>.Ok(result.Select(MapAddonGroupItem).ToList());
    }

    /// <summary>
    /// 保存加料组。
    /// </summary>
    [HttpPost("addon/group/save")]
    [ProducesResponseType(typeof(ApiResponse<ProductAddonGroupItemResponse>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<ProductAddonGroupItemResponse>> SaveAddonGroup(
        [FromBody] SaveProductAddonGroupRequest request,
        CancellationToken cancellationToken)
    {
        // 1. 校验门店访问权限。
        var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
        await EnsureStoreAccessibleAsync(storeId, cancellationToken);

        // 2. 提交保存命令。
        var result = await mediator.Send(new SaveProductAddonGroupCommand
        {
            StoreId = storeId,
            GroupId = StoreApiHelpers.ParseSnowflakeOrNull(request.Id),
            Name = request.Name,
            Description = request.Description,
            Required = request.Required,
            MinSelect = request.MinSelect,
            MaxSelect = request.MaxSelect,
            Sort = request.Sort,
            Status = request.Status,
            ProductIds = StoreApiHelpers.ParseSnowflakeList(request.ProductIds),
            Items = (request.Items ?? [])
                .Select(item => new SaveProductAddonItemCommand
                {
                    Id = StoreApiHelpers.ParseSnowflakeOrNull(item.Id),
                    Name = item.Name,
                    Price = item.Price,
                    Stock = item.Stock,
                    Sort = item.Sort,
                    Status = item.Status
                })
                .ToList()
        }, cancellationToken);

        return ApiResponse<ProductAddonGroupItemResponse>.Ok(MapAddonGroupItem(result));
    }

    /// <summary>
    /// 删除加料组。
    /// </summary>
    [HttpPost("addon/group/delete")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<object>> DeleteAddonGroup(
        [FromBody] DeleteProductAddonGroupRequest request,
        CancellationToken cancellationToken)
    {
        // 1. 校验门店访问权限。
        var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
        await EnsureStoreAccessibleAsync(storeId, cancellationToken);

        // 2. 提交删除命令。
        await mediator.Send(new DeleteProductAddonGroupCommand
        {
            StoreId = storeId,
            GroupId = StoreApiHelpers.ParseRequiredSnowflake(request.GroupId, nameof(request.GroupId))
        }, cancellationToken);

        return ApiResponse<object>.Ok(null);
    }

    /// <summary>
    /// 修改加料组状态。
    /// </summary>
    [HttpPost("addon/group/status")]
    [ProducesResponseType(typeof(ApiResponse<ProductAddonGroupItemResponse>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<ProductAddonGroupItemResponse>> ChangeAddonGroupStatus(
        [FromBody] ChangeProductAddonGroupStatusRequest request,
        CancellationToken cancellationToken)
    {
        // 1. 校验门店访问权限。
        var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
        await EnsureStoreAccessibleAsync(storeId, cancellationToken);

        // 2. 提交状态命令并返回更新后的快照。
        var result = await mediator.Send(new ChangeProductAddonGroupStatusCommand
        {
            StoreId = storeId,
            GroupId = StoreApiHelpers.ParseRequiredSnowflake(request.GroupId, nameof(request.GroupId)),
            Status = request.Status
        }, cancellationToken);

        return ApiResponse<ProductAddonGroupItemResponse>.Ok(MapAddonGroupItem(result));
    }

    /// <summary>
    /// 绑定加料组商品。
    /// </summary>
    [HttpPost("addon/group/products/bind")]
    [ProducesResponseType(typeof(ApiResponse<ProductAddonGroupItemResponse>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<ProductAddonGroupItemResponse>> BindAddonGroupProducts(
        [FromBody] BindProductAddonGroupProductsRequest request,
        CancellationToken cancellationToken)
    {
        // 1. 校验门店访问权限。
        var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
        await EnsureStoreAccessibleAsync(storeId, cancellationToken);

        // 2. 提交绑定命令并返回更新后的快照。
        var result = await mediator.Send(new BindProductAddonGroupProductsCommand
        {
            StoreId = storeId,
            GroupId = StoreApiHelpers.ParseRequiredSnowflake(request.GroupId, nameof(request.GroupId)),
            ProductIds = StoreApiHelpers.ParseSnowflakeList(request.ProductIds)
        }, cancellationToken);

        return ApiResponse<ProductAddonGroupItemResponse>.Ok(MapAddonGroupItem(result));
    }

    private async Task EnsureStoreAccessibleAsync(long storeId, CancellationToken cancellationToken)
    {
        // 1. 读取当前租户上下文。
        var (tenantId, merchantId) = StoreApiHelpers.GetTenantMerchantContext(storeContextService);

        // 2. 校验门店是否属于当前租户商户。
        await StoreApiHelpers.EnsureStoreAccessibleAsync(dbContext, tenantId, merchantId, storeId, cancellationToken);
    }

    private static ProductAddonGroupItemResponse MapAddonGroupItem(ProductAddonTemplateItemDto source)
    {
        // 1. 映射加料项列表。
        var items = source.Items
            .Select(item => new ProductAddonItemResponse
            {
                Id = item.Id.ToString(),
                Name = item.Name,
                Price = item.Price,
                Stock = item.Stock,
                Sort = item.Sort,
                Status = item.Status
            })
            .ToList();

        // 2. 映射加料组响应。
        return new ProductAddonGroupItemResponse
        {
            Id = source.Id.ToString(),
            Name = source.Name,
            Description = source.Description,
            Required = source.Required,
            MinSelect = source.MinSelect,
            MaxSelect = source.MaxSelect,
            Sort = source.Sort,
            Status = source.Status,
            ProductCount = source.ProductCount,
            ProductIds = source.ProductIds.Select(item => item.ToString()).ToList(),
            Items = items,
            UpdatedAt = source.UpdatedAt.ToString("yyyy-MM-dd HH:mm:ss")
        };
    }
}
