// EN: Handler for CreateTableCommand.
// VI: Handler cho CreateTableCommand.

using MediatR;
using FnbEngine.Domain.AggregatesModel.TableAggregate;

namespace FnbEngine.API.Application.Commands;

/// <summary>
/// EN: Handler for creating a new table.
/// VI: Handler tạo bàn mới.
/// </summary>
public class CreateTableCommandHandler : IRequestHandler<CreateTableCommand, CreateTableResult>
{
    private readonly ITableRepository _tableRepository;
    private readonly ILogger<CreateTableCommandHandler> _logger;

    public CreateTableCommandHandler(
        ITableRepository tableRepository,
        ILogger<CreateTableCommandHandler> logger)
    {
        _tableRepository = tableRepository ?? throw new ArgumentNullException(nameof(tableRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<CreateTableResult> Handle(CreateTableCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Creating table {TableNumber} for shop {ShopId}",
            request.TableNumber, request.ShopId);

        // EN: Check if table number already exists for this shop
        // VI: Kiểm tra số bàn đã tồn tại cho shop chưa
        var existingTable = await _tableRepository.GetByNumberAsync(
            request.ShopId, request.TableNumber, cancellationToken);

        if (existingTable != null)
        {
            throw new InvalidOperationException(
                $"Table number '{request.TableNumber}' already exists for this shop");
        }

        // EN: Create table through domain model
        // VI: Tạo bàn thông qua domain model
        var table = new Table(
            request.ShopId,
            request.TableNumber,
            request.Capacity,
            request.Zone);

        await _tableRepository.AddAsync(table, cancellationToken);
        await _tableRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Created table {TableId} for shop {ShopId}",
            table.Id, request.ShopId);

        return new CreateTableResult(table.Id);
    }
}
