using CMSMicroservice.Application.Common.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace CMSMicroservice.Application.DiscountShopCQ.Commands.UpdateDiscountCategory;

public class UpdateDiscountCategoryCommandHandler : IRequestHandler<UpdateDiscountCategoryCommand, bool>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<bool> Handle(UpdateDiscountCategoryCommand request, CancellationToken cancellationToken)
    {
        var category = await _context.DiscountCategories
            .FirstOrDefaultAsync(c => c.Id == request.CategoryId, cancellationToken);

        if (category == null)
        {
            return false;
        }

        // بررسی وجود دسته‌بندی دیگری با همین نام (به جز خودش)
        var duplicateName = await _context.DiscountCategories
            .AnyAsync(c => c.Name == request.Name && c.Id != request.CategoryId, cancellationToken);

        if (duplicateName)
        {
            throw new InvalidOperationException("دسته‌بندی دیگری با این نام وجود دارد");
        }

        // بررسی عدم ایجاد حلقه در سلسله مراتب
        if (request.ParentCategoryId.HasValue)
        {
            if (request.ParentCategoryId.Value == request.CategoryId)
            {
                throw new InvalidOperationException("دسته‌بندی نمی‌تواند والد خودش باشد");
            }

            // بررسی وجود دسته‌بندی والد
            var parentExists = await _context.DiscountCategories
                .AnyAsync(c => c.Id == request.ParentCategoryId.Value, cancellationToken);

            if (!parentExists)
            {
                throw new InvalidOperationException("دسته‌بندی والد یافت نشد");
            }

            // بررسی اینکه والد جدید زیرمجموعه این دسته‌بندی نباشد
            var isDescendant = await IsDescendant(request.ParentCategoryId.Value, request.CategoryId, cancellationToken);
            if (isDescendant)
            {
                throw new InvalidOperationException("دسته‌بندی والد نمی‌تواند زیرمجموعه این دسته‌بندی باشد");
            }
        }

        category.Name = request.Name;
        category.Title = request.Title;
        category.Description = request.Description;
        category.ImagePath = request.ImagePath;
        category.ParentCategoryId = request.ParentCategoryId;
        category.SortOrder = request.SortOrder;
        category.IsActive = request.IsActive;

        await _context.SaveChangesAsync(cancellationToken);

        return true;
    }

    private async Task<bool> IsDescendant(long potentialDescendantId, long ancestorId, CancellationToken cancellationToken)
    {
        var category = await _context.DiscountCategories
            .FirstOrDefaultAsync(c => c.Id == potentialDescendantId, cancellationToken);

        if (category == null || !category.ParentCategoryId.HasValue)
        {
            return false;
        }

        if (category.ParentCategoryId.Value == ancestorId)
        {
            return true;
        }

        return await IsDescendant(category.ParentCategoryId.Value, ancestorId, cancellationToken);
    }
}
