using CMSMicroservice.Application.Common.FileManager;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Enums;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.Application.ProductsCQ.Commands.CreateNewProducts;

public class CreateNewProductsCommandHandler : IRequestHandler<CreateNewProductsCommand, CreateNewProductsResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IFileManager _fileManager;
    private readonly IInventoryService _inventoryService;
    private readonly ILogger<CreateNewProductsCommandHandler> _logger;

    public CreateNewProductsCommandHandler(
        IApplicationDbContext context,
        IFileManager fileManager,
        IInventoryService inventoryService,
        ILogger<CreateNewProductsCommandHandler> logger)
    {
        _context = context;
        _fileManager = fileManager;
        _inventoryService = inventoryService;
        _logger = logger;
    }

    public async Task<CreateNewProductsResponseDto> Handle(CreateNewProductsCommand request,
        CancellationToken cancellationToken)
    {
        var entity = new Product
        {
            Title = request.Title,
            Description = request.Description,
            ShortInfomation = request.ShortInfomation,
            FullInformation = request.FullInformation,
            Price = request.Price,
            Discount = request.Discount,
            Rate = request.Rate,
            ImagePath = string.Empty,
            ThumbnailPath = string.Empty,
            SaleCount = request.SaleCount,
            ViewCount = request.ViewCount,
            RemainingCount = request.RemainingCount
        };

        // آپلود تصویر اصلی (اگر ارسال شده باشد)
        if (request.ImageFileBytes is { Length: > 0 })
        {
            var result = await _fileManager.UploadImageAsync(
                "Images/Products",
                request.ImageFileBytes,
                request.ImageFileMime ?? "image/jpeg",
                request.ImageFileName,
                cancellationToken);

            entity.ImagePath = result.Main.Path;
            entity.ThumbnailPath = result.Thumbnail.Path;
        }

        // آپلود بندانگشتی جداگانه (اختیاری — جایگزین بندانگشتی خودکار)
        if (request.ThumbnailFileBytes is { Length: > 0 })
        {
            var thumbResult = await _fileManager.UploadAsync(
                "Images/Products/Thumbnails",
                request.ThumbnailFileBytes,
                request.ThumbnailFileMime ?? "image/jpeg",
                request.ThumbnailFileName,
                cancellationToken);

            entity.ThumbnailPath = thumbResult.Path;
        }

        await _context.Products.AddAsync(entity, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);

        // ایجاد رکورد موجودی در سیستم انبارداری
        try
        {
            await _inventoryService.InitializeInventoryAsync(
                entity.Id,
                ProductType.RegularProduct,
                0, // موجودی اولیه صفر — باید از طریق Inventory اضافه شود
                ct: cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to initialize inventory for Product Id={ProductId}", entity.Id);
        }

        // Handle category assignments
        if (request.CategoryIds is { Count: > 0 })
        {
            foreach (var categoryId in request.CategoryIds)
            {
                var categoryExists = await _context.Categories
                    .AnyAsync(c => c.Id == categoryId, cancellationToken);
                    
                if (categoryExists)
                {
                    await _context.ProductCategories.AddAsync(new ProductCategory
                    {
                        ProductId = entity.Id,
                        CategoryId = categoryId
                    }, cancellationToken);
                }
            }
            await _context.SaveChangesAsync(cancellationToken);
        }

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