using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Enums;

namespace CMSMicroservice.Application.InventoryItemCQ.Commands.CreateInventoryItem;

public class CreateInventoryItemCommandHandler : IRequestHandler<CreateInventoryItemCommand, CreateInventoryItemResponseDto>
{
    private readonly IApplicationDbContext _context;

    public CreateInventoryItemCommandHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<CreateInventoryItemResponseDto> Handle(CreateInventoryItemCommand request, CancellationToken cancellationToken)
    {
        // بررسی اینکه حداقل یکی از Product یا DiscountProduct تعریف شده باشد
        if (request.ProductId == null && request.DiscountProductId == null)
        {
            throw new ArgumentException("Either ProductId or DiscountProductId must be provided");
        }

        // بررسی اینکه هر دو ProductId و DiscountProductId تعریف نشده باشند
        if (request.ProductId != null && request.DiscountProductId != null)
        {
            throw new ArgumentException("Only one of ProductId or DiscountProductId can be provided");
        }

        // بررسی وجود آیتم موجودی قبلی برای همین محصول در همین انبار
        bool existingItem;
        if (request.ProductId.HasValue)
        {
            existingItem = await _context.InventoryItems
                .AnyAsync(i => i.ProductId == request.ProductId.Value && i.WarehouseId == request.WarehouseId, cancellationToken);
        }
        else
        {
            existingItem = await _context.InventoryItems
                .AnyAsync(i => i.DiscountProductId == request.DiscountProductId!.Value && i.WarehouseId == request.WarehouseId, cancellationToken);
        }

        if (existingItem)
        {
            throw new InvalidOperationException("Inventory item already exists for this product in this warehouse");
        }

        var productType = request.ProductId.HasValue ? ProductType.RegularProduct : ProductType.DiscountProduct;

        var entity = new InventoryItem
        {
            ProductId = request.ProductId,
            DiscountProductId = request.DiscountProductId,
            ProductType = productType,
            WarehouseId = request.WarehouseId,
            Quantity = request.Quantity,
            LowStockThreshold = request.MinQuantity,
            MaxStockLevel = request.MaxQuantity,
            ReservedQuantity = 0
        };

        await _context.InventoryItems.AddAsync(entity, cancellationToken);

        // ثبت حرکت موجودی اولیه اگر موجودی اولیه بیشتر از صفر باشد
        if (request.Quantity > 0)
        {
            var stockMovement = new StockMovement
            {
                InventoryItemId = entity.Id,
                MovementType = StockMovementType.InitialStock,
                Quantity = request.Quantity,
                QuantityBefore = 0,
                QuantityAfter = request.Quantity,
                Note = "Initial stock creation",
                ReferenceNumber = $"INIT-{entity.Id}"
            };

            await _context.StockMovements.AddAsync(stockMovement, cancellationToken);
        }

        await _context.SaveChangesAsync(cancellationToken);

        return new CreateInventoryItemResponseDto { Id = entity.Id };
    }
}
