using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Inventory.Commands;
using TakeoutSaaS.Application.App.Inventory.Dto;
using TakeoutSaaS.Domain.Inventory.Entities;
using TakeoutSaaS.Domain.Inventory.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Inventory.Handlers;

/// <summary>
/// 批次维护处理器。
/// </summary>
public sealed class UpsertInventoryBatchCommandHandler(
    IInventoryRepository inventoryRepository,
    ITenantProvider tenantProvider,
    ILogger<UpsertInventoryBatchCommandHandler> logger)
    : IRequestHandler<UpsertInventoryBatchCommand, InventoryBatchDto>
{
    /// <inheritdoc />
    public async Task<InventoryBatchDto> Handle(UpsertInventoryBatchCommand request, CancellationToken cancellationToken)
    {
        // 1. 读取批次
        var tenantId = tenantProvider.GetCurrentTenantId();
        var batch = await inventoryRepository.GetBatchForUpdateAsync(tenantId, request.StoreId, request.ProductSkuId, request.BatchNumber, cancellationToken);
        // 2. 创建或更新
        if (batch is null)
        {
            batch = new InventoryBatch
            {
                TenantId = tenantId,
                StoreId = request.StoreId,
                ProductSkuId = request.ProductSkuId,
                BatchNumber = request.BatchNumber,
                ProductionDate = request.ProductionDate,
                ExpireDate = request.ExpireDate,
                Quantity = request.Quantity,
                RemainingQuantity = request.RemainingQuantity
            };
            await inventoryRepository.AddBatchAsync(batch, cancellationToken);
        }
        else
        {
            batch.ProductionDate = request.ProductionDate;
            batch.ExpireDate = request.ExpireDate;
            batch.Quantity = request.Quantity;
            batch.RemainingQuantity = request.RemainingQuantity;
            await inventoryRepository.UpdateBatchAsync(batch, cancellationToken);
        }

        await inventoryRepository.SaveChangesAsync(cancellationToken);
        logger.LogInformation("维护批次 门店 {StoreId} SKU {ProductSkuId} 批次 {BatchNumber}", request.StoreId, request.ProductSkuId, request.BatchNumber);
        return InventoryMapping.ToDto(batch);
    }
}
