using Microsoft.AspNetCore.Components;
using MudBlazor;
using Google.Protobuf.WellKnownTypes;
using CMSMicroservice.Protobuf.Protos.Inventory;
using BackOffice.Pages.Inventory.Components;
using BackOffice.Common.Utilities;
using Microsoft.JSInterop;
using System.Text;

namespace BackOffice.Pages.Inventory;

public partial class InventoryMainPage
{
    [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
    [Inject] public IJSRuntime JsRuntime { get; set; } = default!;

    private MudDataGrid<InventoryItemDto>? _gridData;
    private List<WarehouseDto> _warehouses = new();
    
    // Filter fields
    private long? _filterWarehouseId;
    private ProductType _filterProductType = ProductType.Unspecified;
    private string _searchTerm = string.Empty;
    
    // Stats
    private int _totalCount;
    private int _lowStockCount;

    protected override async Task OnInitializedAsync()
    {
        await LoadWarehouses();
        await LoadLowStockCount();
    }

    private async Task LoadWarehouses()
    {
        try
        {
            var response = await InventoryContract.GetAllWarehousesAsync(new GetAllWarehousesRequest
            {
                IsActive = true
            });
            _warehouses = response.Warehouses.ToList();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در بارگذاری انبارها: {ex.Message}", Severity.Error);
        }
    }

    private async Task LoadLowStockCount()
    {
        try
        {
            var response = await InventoryContract.GetLowStockItemsAsync(new GetLowStockItemsRequest
            {
                Page = 1,
                PageSize = 100 // Get up to 100 low stock items to count
            });
            _lowStockCount = response.TotalCount;
        }
        catch
        {
            _lowStockCount = 0;
        }
    }

    private async Task<GridData<InventoryItemDto>> ServerReload(GridState<InventoryItemDto> state)
    {
        try
        {
            var request = new GetAllInventoryItemsRequest
            {
                Page = state.Page + 1,
                PageSize = state.PageSize,
                ProductType = _filterProductType,
                Search = _searchTerm ?? string.Empty
            };

            if (_filterWarehouseId.HasValue)
            {
                request.WarehouseId = _filterWarehouseId.Value;
            }

            var result = await InventoryContract.GetAllInventoryItemsAsync(request);

            if (result?.Items != null)
            {
                _totalCount = result.TotalCount;
                return new GridData<InventoryItemDto>
                {
                    Items = result.Items.ToList(),
                    TotalItems = result.TotalCount
                };
            }

            return new GridData<InventoryItemDto>();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در بارگذاری داده‌ها: {ex.Message}", Severity.Error);
            return new GridData<InventoryItemDto>();
        }
    }

    private string GetProductTypeLabel(ProductType type)
    {
        return type switch
        {
            ProductType.RegularProduct => "محصول عادی",
            ProductType.DiscountProduct => "محصول تخفیفی",
            _ => "نامشخص"
        };
    }

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

    private async Task ClearFilter()
    {
        _filterWarehouseId = null;
        _filterProductType = ProductType.Unspecified;
        _searchTerm = string.Empty;
        await ApplyFilter();
    }

    private async Task OpenAddStockDialog()
    {
        var parameters = new DialogParameters
        {
            ["Warehouses"] = _warehouses
        };

        var dialog = await DialogService.ShowAsync<AddStockDialog>("ورود کالا به انبار", parameters, new DialogOptions
        {
            CloseButton = true,
            MaxWidth = MaxWidth.Medium,
            FullWidth = true
        });

        var result = await dialog.Result;
        if (!result!.Canceled)
        {
            Snackbar.Add("موجودی با موفقیت اضافه شد", Severity.Success);
            await ApplyFilter();
            await LoadLowStockCount();
        }
    }

    private async Task OpenAddStockDialogForItem(InventoryItemDto item)
    {
        var parameters = new DialogParameters
        {
            ["Warehouses"] = _warehouses,
            ["ProductIdParam"] = item.ProductType == ProductType.RegularProduct ? item.ProductId : item.DiscountProductId,
            ["ProductTypeParam"] = item.ProductType,
            ["ProductName"] = item.ProductTitle,
            ["WarehouseIdParam"] = item.WarehouseId
        };

        var dialog = await DialogService.ShowAsync<AddStockDialog>($"ورود کالا - {item.ProductTitle}", parameters, new DialogOptions
        {
            CloseButton = true,
            MaxWidth = MaxWidth.Medium,
            FullWidth = true
        });

        var result = await dialog.Result;
        if (!result!.Canceled)
        {
            Snackbar.Add("موجودی با موفقیت اضافه شد", Severity.Success);
            await ApplyFilter();
            await LoadLowStockCount();
        }
    }

    private async Task OpenAdjustStockDialog(InventoryItemDto item)
    {
        var parameters = new DialogParameters
        {
            ["Item"] = item
        };

        var dialog = await DialogService.ShowAsync<AdjustStockDialog>($"تنظیم موجودی - {item.ProductTitle}", parameters, new DialogOptions
        {
            CloseButton = true,
            MaxWidth = MaxWidth.Small,
            FullWidth = true
        });

        var result = await dialog.Result;
        if (!result!.Canceled)
        {
            Snackbar.Add("موجودی با موفقیت تنظیم شد", Severity.Success);
            await ApplyFilter();
            await LoadLowStockCount();
        }
    }

    private async Task OpenRecordLossDialog(InventoryItemDto item)
    {
        var parameters = new DialogParameters
        {
            ["Item"] = item
        };

        var dialog = await DialogService.ShowAsync<RecordLossDialog>($"ثبت خسارت - {item.ProductTitle}", parameters, new DialogOptions
        {
            CloseButton = true,
            MaxWidth = MaxWidth.Small,
            FullWidth = true
        });

        var result = await dialog.Result;
        if (!result!.Canceled)
        {
            Snackbar.Add("خسارت با موفقیت ثبت شد", Severity.Warning);
            await ApplyFilter();
            await LoadLowStockCount();
        }
    }

    private async Task OpenSettingsDialog(InventoryItemDto item)
    {
        var parameters = new DialogParameters
        {
            ["Item"] = item
        };

        var dialog = await DialogService.ShowAsync<InventorySettingsDialog>($"تنظیمات - {item.ProductTitle}", parameters, new DialogOptions
        {
            CloseButton = true,
            MaxWidth = MaxWidth.Small,
            FullWidth = true
        });

        var result = await dialog.Result;
        if (!result!.Canceled)
        {
            Snackbar.Add("تنظیمات با موفقیت ذخیره شد", Severity.Success);
            await ApplyFilter();
        }
    }

    private void ViewMovements(InventoryItemDto item)
    {
        Navigation.NavigateTo($"{RouteConstance.InventoryMovements}?itemId={item.Id}&productName={item.ProductTitle}");
    }

    private async Task ExportToExcel()
    {
        try
        {
            var request = new GetAllInventoryItemsRequest
            {
                Page = 1,
                PageSize = 1000,
                ProductType = _filterProductType,
                Search = _searchTerm ?? string.Empty
            };

            if (_filterWarehouseId.HasValue)
            {
                request.WarehouseId = _filterWarehouseId.Value;
            }

            var result = await InventoryContract.GetAllInventoryItemsAsync(request);

            if (result?.Items == null || !result.Items.Any())
            {
                Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info);
                return;
            }

            var sb = new StringBuilder();
            sb.AppendLine("شناسه,محصول,انبار,موجودی,رزرو,قابل فروش,حد هشدار,وضعیت");

            foreach (var i in result.Items)
            {
                sb.AppendLine(string.Join(",",
                    i.Id,
                    EscapeCsv(i.ProductTitle),
                    EscapeCsv(i.WarehouseName),
                    i.Quantity,
                    i.ReservedQuantity,
                    i.AvailableQuantity,
                    i.LowStockThreshold,
                    i.IsLowStock ? "کمبود" : "عادی"));
            }

            var bytes = Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes(sb.ToString())).ToArray();
            var base64 = Convert.ToBase64String(bytes);
            var filename = $"inventory-{DateTime.Now:yyyyMMddHHmmss}.csv";

            await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename, base64);
            Snackbar.Add("خروجی Excel (CSV) آماده شد.", Severity.Success);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در خروجی Excel: {ex.Message}", Severity.Error);
        }
    }

    private static string EscapeCsv(string value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        if (value.Contains(',') || value.Contains('"') || value.Contains('\n'))
            return $"\"{value.Replace("\"", "\"\"")}\"";
        return value;
    }
}
