using CMSMicroservice.Protobuf.Protos.Products;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MudBlazor;

namespace BackOffice.Pages.Products;

public partial class ProductCategoriesDragDropPage
{
    [Parameter] public long? ProductId { get; set; }

    [Inject] public ProductsContract.ProductsContractClient ProductsContract { get; set; } = default!;

    private long? _selectedProductId;
    private bool _isLoading;
    private bool _isSaving;
    private string? _productTitle;
    private List<CategoryItem> _categories = new();
    private long? _draggingCategoryId;

    private List<CategoryItem> SelectedCategories => _categories.Where(c => c.Selected).ToList();
    private List<CategoryItem> UnselectedCategories => _categories.Where(c => !c.Selected).ToList();

    protected override async Task OnInitializedAsync()
    {
        if (ProductId.HasValue && ProductId.Value > 0)
        {
            _selectedProductId = ProductId.Value;
            await LoadProductAndCategories(ProductId.Value);
        }
    }

    private async Task OnProductChanged(long? productId)
    {
        _selectedProductId = productId;
        _categories.Clear();

        if (productId.HasValue)
        {
            await LoadProductAndCategories(productId.Value);
        }
    }

    private async Task LoadProductAndCategories(long productId)
    {
        await LoadProductTitle(productId);
        await LoadCategories(productId);
    }

    private async Task LoadProductTitle(long productId)
    {
        try
        {
            var response = await ProductsContract.GetProductsAsync(new GetProductsRequest
            {
                Id = productId
            });

            _productTitle = response?.Title;
        }
        catch
        {
            _productTitle = null;
        }
    }

    private async Task LoadCategories(long productId)
    {
        _isLoading = true;
        StateHasChanged();

        try
        {
            var response = await ProductsContract.GetCategoriesAsync(new GetCategoriesRequest
            {
                ProductId = productId
            });

            _categories = response?.Items?.ToList() ?? new List<CategoryItem>();
        }
        catch
        {
            Snackbar.Add("در بازیابی دسته‌بندی‌های محصول خطایی رخ داد.", Severity.Error);
        }
        finally
        {
            _isLoading = false;
            StateHasChanged();
        }
    }

    private void OnDragStart(long categoryId)
    {
        _draggingCategoryId = categoryId;
    }

    private void OnDragOver(DragEventArgs args)
    {
        // Allow dropping by preventing default behavior
    }

    private void ToggleCategory(long categoryId)
    {
        var item = _categories.FirstOrDefault(c => c.Id == categoryId);
        if (item == null)
            return;

        item.Selected = !item.Selected;
    }

    private void HandleDrop(bool targetSelected)
    {
        if (_draggingCategoryId == null)
            return;

        var item = _categories.FirstOrDefault(c => c.Id == _draggingCategoryId.Value);
        if (item == null)
            return;

        item.Selected = targetSelected;

        _draggingCategoryId = null;
        StateHasChanged();
    }

    private void OnDropOnSelected(DragEventArgs args) => HandleDrop(true);

    private void OnDropOnUnselected(DragEventArgs args) => HandleDrop(false);

    private async Task SaveCategories()
    {
        if (!_selectedProductId.HasValue)
            return;

        _isSaving = true;
        StateHasChanged();

        try
        {
            var request = new UpdateProductCategoriesRequest
            {
                ProductId = _selectedProductId.Value
            };

            request.CategoryIds.AddRange(
                _categories.Where(c => c.Selected).Select(c => c.Id));

            await ProductsContract.UpdateProductCategoriesAsync(request);

            Snackbar.Add("دسته‌بندی‌های محصول با موفقیت به‌روزرسانی شد.", Severity.Success);
        }
        catch
        {
            Snackbar.Add("در ذخیره‌سازی دسته‌بندی‌ها خطایی رخ داد.", Severity.Error);
        }
        finally
        {
            _isSaving = false;
            StateHasChanged();
        }
    }
}
