using CMSMicroservice.Protobuf.Protos.Products;
using CMSMicroservice.Protobuf.Protos.Products;
using Microsoft.AspNetCore.Components;
using MudBlazor;
using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel;
using PaginationState = CMSMicroservice.Protobuf.Protos.PaginationState;

namespace BackOffice.Pages.Products;

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

    private BackOffice.Common.BaseComponents.BasePageComponent _basePage = default!;
    private MudDataGrid<DataModel> _gridData = default!;

    private GetAllProductsByFilterRequest _request = new() { Filter = new() };
    private readonly HashSet<long> _selectedProductIds = new();

    private bool _isLoading;
    private bool _isApplying;

    private long? _newPrice;
    private int? _newDiscount;
    private int? _newClubDiscountPercent;

    private bool? _statusEnable;

    private async Task<GridData<DataModel>> ServerReload(GridState<DataModel> state)
    {
        _isLoading = true;
        StateHasChanged();

        _selectedProductIds.Clear();

        _request.Filter ??= new();
        _request.PaginationState ??= new PaginationState();
        _request.PaginationState.PageNumber = state.Page + 1;
        _request.PaginationState.PageSize = state.PageSize;

        var result = await ProductsContract.GetAllProductsByFilterAsync(_request);

        _isLoading = false;
        StateHasChanged();

        if (result != null && result.Models != null && result.Models.Any())
        {
            return new GridData<DataModel>
            {
                Items = result.Models.ToList(),
                TotalItems = (int)result.MetaData.TotalCount
            };
        }

        return new GridData<DataModel>();
    }

    private void ToggleSelection(long id, bool isSelected)
    {
        if (isSelected)
        {
            _selectedProductIds.Add(id);
        }
        else
        {
            _selectedProductIds.Remove(id);
        }
    }

    public async Task OnFilterSubmit()
    {
        _basePage.IsFiltered = true;
        StateHasChanged();
        await ReloadData();
    }

    public async Task OnFilterCleared()
    {
        _basePage.IsFiltered = false;
        StateHasChanged();
        _request = new GetAllProductsByFilterRequest { Filter = new() };
        await ReloadData();
    }

    private async Task ReloadData()
    {
        if (_gridData != null)
        {
            await _gridData.ReloadServerData();
        }
    }

    private void ClearForm()
    {
        _newPrice = null;
        _newDiscount = null;
        _newClubDiscountPercent = null;
        _statusEnable = null;
    }

    private async Task ApplyBulkChanges()
    {
        if (_selectedProductIds.Count == 0)
        {
            Snackbar.Add("هیچ محصولی برای ویرایش انتخاب نشده است.", Severity.Warning);
            return;
        }

        var hasPriceChanges = _newPrice.HasValue;
        var hasStatusChange = _statusEnable.HasValue;

        if (!hasPriceChanges && !hasStatusChange)
        {
            Snackbar.Add("هیچ تغییری برای اعمال انتخاب نشده است.", Severity.Warning);
            return;
        }

        var confirmationText = BuildConfirmationText(hasPriceChanges, hasStatusChange);

        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small };
        bool? confirmed = await DialogService.ShowMessageBox(
            "تأیید ویرایش گروهی",
            confirmationText,
            yesText: "اعمال تغییرات",
            cancelText: "لغو",
            options: options);

        if (confirmed != true)
            return;

        _isApplying = true;
        StateHasChanged();

        try
        {
            int total = 0;
            int succeeded = 0;
            int failed = 0;

            if (hasPriceChanges)
            {
                var priceRequest = new BulkUpdateProductPricesRequest();

                foreach (var id in _selectedProductIds)
                {
                    var update = new ProductPriceUpdate
                    {
                        ProductId = id,
                        NewPrice = _newPrice!.Value
                    };

                    if (_newDiscount.HasValue)
                    {
                        update.NewDiscount = _newDiscount.Value;
                    }

                    if (_newClubDiscountPercent.HasValue)
                    {
                        update.NewClubDiscountPercent = _newClubDiscountPercent.Value;
                    }

                    priceRequest.Products.Add(update);
                }

                var priceResponse = await ProductsContract.BulkUpdateProductPricesAsync(priceRequest);

                if (priceResponse != null)
                {
                    total += priceResponse.Total;
                    succeeded += priceResponse.Succeeded;
                    failed += priceResponse.Failed;
                }
            }

            if (hasStatusChange)
            {
                var toggleRequest = new ToggleProductStatusRequest
                {
                    Enable = _statusEnable!.Value,
                    DefaultStock = 0
                };

                toggleRequest.ProductIds.AddRange(_selectedProductIds);

                var toggleResponse = await ProductsContract.ToggleProductStatusAsync(toggleRequest);

                if (toggleResponse != null)
                {
                    total += toggleResponse.Total;
                    succeeded += toggleResponse.Succeeded;
                    failed += toggleResponse.Failed;
                }
            }

            if (failed == 0)
            {
                Snackbar.Add($"تغییرات گروهی با موفقیت برای {succeeded} مورد اعمال شد.", Severity.Success);
            }
            else
            {
                Snackbar.Add($"تغییرات گروهی انجام شد. موفق: {succeeded} / ناموفق: {failed}", Severity.Warning);
            }

            await ReloadData();
            _selectedProductIds.Clear();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در اعمال تغییرات گروهی: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isApplying = false;
            StateHasChanged();
        }
    }

    private string BuildConfirmationText(bool hasPriceChanges, bool hasStatusChange)
    {
        var parts = new List<string>();

        if (hasPriceChanges)
        {
            var pricePart = $"• قیمت جدید: {_newPrice?.ToString("N0") ?? "-"}";

            if (_newDiscount.HasValue)
                pricePart += $", تخفیف: {_newDiscount.Value}%";

            if (_newClubDiscountPercent.HasValue)
                pricePart += $", تخفیف باشگاه: {_newClubDiscountPercent.Value}%";

            parts.Add(pricePart);
        }

        if (hasStatusChange)
        {
            var statusText = _statusEnable == true ? "فعال‌سازی" : "غیرفعال‌سازی";
            parts.Add($"• {statusText} محصولات انتخاب‌شده");
        }

        return $"آیا از اعمال تغییرات زیر برای {_selectedProductIds.Count} محصول انتخاب‌شده مطمئن هستید؟\n\n{string.Join("\n", parts)}";
    }
}

