using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities;

namespace CMSMicroservice.Application.ProductsCQ.Queries.GetCustomerProducts;

public class GetCustomerProductsQueryHandler : IRequestHandler<GetCustomerProductsQuery, GetCustomerProductsResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetCustomerProductsResponseDto> Handle(GetCustomerProductsQuery request, CancellationToken cancellationToken)
    {
        var product = await _context.Products
            .AsNoTracking()
            .Where(x => x.Id == request.Id)
            .Include(x => x.ProductGalleries)
                .ThenInclude(pg => pg.ProductImage)
            .Include(x => x.ProductCategories)
                .ThenInclude(pc => pc.Category)
            .FirstOrDefaultAsync(cancellationToken);

        if (product == null)
            throw new NotFoundException(nameof(Product), request.Id);

        var response = new GetCustomerProductsResponseDto
        {
            Id = product.Id,
            Title = product.Title,
            Description = product.Description,
            ShortInfomation = product.ShortInfomation,
            FullInformation = product.FullInformation,
            Price = product.Price,
            Discount = product.Discount,
            Rate = product.Rate,
            ImagePath = product.ImagePath,
            ThumbnailPath = product.ThumbnailPath,
            SaleCount = product.SaleCount,
            ViewCount = product.ViewCount,
            RemainingCount = product.RemainingCount,
            Gallery = product.ProductGalleries?.Select(pg => new ProductGalleryModel
            {
                ProductGalleryId = pg.Id,
                ProductImageId = pg.ProductImageId,
                Title = pg.ProductImage?.Title ?? string.Empty,
                ImagePath = pg.ProductImage?.ImagePath ?? string.Empty,
                ImageThumbnailPath = pg.ProductImage?.ImageThumbnailPath ?? string.Empty
            }).ToList() ?? new List<ProductGalleryModel>(),
            Categories = product.ProductCategories?.Select(pc => new ProductCategoryModel
            {
                CategoryId = pc.CategoryId,
                Title = pc.Category?.Title ?? string.Empty,
                Path = BuildCategoryPath(pc.Category)
            }).ToList() ?? new List<ProductCategoryModel>()
        };

        return response;
    }

    private List<CategoryNodeModel> BuildCategoryPath(Category? category)
    {
        var path = new List<CategoryNodeModel>();
        
        while (category != null)
        {
            path.Insert(0, new CategoryNodeModel
            {
                Id = category.Id,
                Title = category.Title,
                ParentId = category.ParentId
            });
            
            // Move to parent
            if (category.ParentId.HasValue)
            {
                category = _context.Categories
                    .AsNoTracking()
                    .FirstOrDefault(c => c.Id == category.ParentId.Value);
            }
            else
            {
                category = null;
            }
        }
        
        return path;
    }
}
