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

namespace BackOffice.Pages.Inventory;

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

    [SupplyParameterFromQuery(Name = "itemId")]
    public long? ItemId { get; set; }

    [SupplyParameterFromQuery(Name = "productName")]
    public string? _productName { get; set; }

    private MudDataGrid<StockMovementDto>? _gridData;
    private int _totalCount;

    // Filter fields
    private StockMovementType _filterMovementType = StockMovementType.MovementTypeUnspecified;
    private ProductType _filterProductType = ProductType.Unspecified;
    private DateTime? _filterFromDate;
    private DateTime? _filterToDate;

    private async Task<GridData<StockMovementDto>> ServerReload(GridState<StockMovementDto> state)
    {
        try
        {
            var request = new GetStockMovementsRequest
            {
                Page = state.Page + 1,
                PageSize = state.PageSize,
                MovementType = _filterMovementType,
                ProductType = _filterProductType
            };

            if (ItemId.HasValue)
            {
                request.InventoryItemId = ItemId.Value;
            }

            if (_filterFromDate.HasValue)
            {
                request.FromDate = Timestamp.FromDateTime(_filterFromDate.Value.ToUniversalTime());
            }

            if (_filterToDate.HasValue)
            {
                request.ToDate = Timestamp.FromDateTime(_filterToDate.Value.ToUniversalTime());
            }

            var result = await InventoryContract.GetStockMovementsAsync(request);

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

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

    private Color GetMovementColor(StockMovementType type)
    {
        return type switch
        {
            StockMovementType.InitialStock => Color.Info,
            StockMovementType.Restock => Color.Success,
            StockMovementType.Return => Color.Success,
            StockMovementType.Sale => Color.Primary,
            StockMovementType.AdjustmentIncrease => Color.Success,
            StockMovementType.AdjustmentDecrease => Color.Warning,
            StockMovementType.Reserved => Color.Secondary,
            StockMovementType.Released => Color.Tertiary,
            StockMovementType.Loss => Color.Error,
            StockMovementType.Damaged => Color.Error,
            StockMovementType.Expired => Color.Error,
            StockMovementType.TransferOut => Color.Warning,
            StockMovementType.TransferIn => Color.Info,
            _ => Color.Default
        };
    }

    private string GetMovementTypeLabel(StockMovementType type)
    {
        return type switch
        {
            StockMovementType.InitialStock => "موجودی اولیه",
            StockMovementType.Restock => "ورود کالا",
            StockMovementType.Return => "برگشت از مشتری",
            StockMovementType.Sale => "فروش",
            StockMovementType.AdjustmentIncrease => "افزایش موجودی",
            StockMovementType.AdjustmentDecrease => "کاهش موجودی",
            StockMovementType.Reserved => "رزرو",
            StockMovementType.Released => "آزادسازی رزرو",
            StockMovementType.Loss => "خسارت",
            StockMovementType.Damaged => "آسیب‌دیده",
            StockMovementType.Expired => "منقضی",
            StockMovementType.TransferOut => "انتقال به بیرون",
            StockMovementType.TransferIn => "انتقال به داخل",
            _ => "نامشخص"
        };
    }

    private bool IsIncreaseMovement(StockMovementType type)
    {
        return type switch
        {
            StockMovementType.InitialStock => true,
            StockMovementType.Restock => true,
            StockMovementType.Return => true,
            StockMovementType.AdjustmentIncrease => true,
            StockMovementType.Released => true,
            StockMovementType.TransferIn => true,
            _ => false
        };
    }

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

    private async Task ClearFilter()
    {
        _filterMovementType = StockMovementType.MovementTypeUnspecified;
        _filterProductType = ProductType.Unspecified;
        _filterFromDate = null;
        _filterToDate = null;
        await ApplyFilter();
    }

    private void GoBack()
    {
        Navigation.NavigateTo(RouteConstance.Inventory);
    }

    private async Task ExportToExcel()
    {
        try
        {
            var request = new GetStockMovementsRequest
            {
                Page = 1,
                PageSize = 1000,
                MovementType = _filterMovementType,
                ProductType = _filterProductType
            };

            if (ItemId.HasValue) request.InventoryItemId = ItemId.Value;
            if (_filterFromDate.HasValue) request.FromDate = Timestamp.FromDateTime(_filterFromDate.Value.ToUniversalTime());
            if (_filterToDate.HasValue) request.ToDate = Timestamp.FromDateTime(_filterToDate.Value.ToUniversalTime());

            var result = await InventoryContract.GetStockMovementsAsync(request);

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

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

            foreach (var m in result.Movements)
            {
                sb.AppendLine(string.Join(",",
                    m.Id,
                    EscapeCsv(m.ProductTitle),
                    EscapeCsv(GetMovementTypeLabel(m.MovementType)),
                    m.Quantity,
                    m.QuantityBefore,
                    m.QuantityAfter,
                    EscapeCsv(m.ReferenceNumber),
                    EscapeCsv(m.Note),
                    m.Created?.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() ?? "-"));
            }

            var bytes = Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes(sb.ToString())).ToArray();
            var base64 = Convert.ToBase64String(bytes);
            var filename = $"stock-movements-{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;
    }
}
