using System.Linq;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.WebUtilities;
using FrontOffice.Main.Utilities;

namespace FrontOffice.Main.Pages.Store;

public enum ProductSortOption
{
    PriceDesc,  // گران‌ترین (پیش‌فرض)
    PriceAsc,   // ارزان‌ترین
    Newest,     // جدیدترین
    Title       // الفبایی
}

public partial class Products : ComponentBase, IDisposable
{
    [Inject] private ProductService ProductService { get; set; } = default!;
    [Inject] private CategoryService CategoryService { get; set; } = default!;
    [Inject] private CartService Cart { get; set; } = default!;
    [Inject] private VATService VAT { get; set; } = default!;
    [Inject] private GuestActionGate GuestGate { get; set; } = default!;
    [Inject] private AuthService AuthService { get; set; } = default!;

    private bool _isAuthenticated;
    private string _query = string.Empty;
    private bool _loading;
    private bool _loadingMore;
    private bool _hasMore = true;
    private int _currentPage = 1;
    private int _totalCount;
    private const int PageSize = 12;
    private List<Product> _products = new();
    private long? _activeCategoryId;
    private string? _activeCategoryTitle;
    
    private ProductSortOption _sortOption = ProductSortOption.PriceDesc; // پیش‌فرض: گران‌ترین

    protected override async Task OnInitializedAsync()
    {
        _isAuthenticated = await AuthService.IsAuthenticatedAsync();
        await Cart.EnsureInitializedAsync();
        Cart.OnChange += StateHasChanged;
        Navigation.LocationChanged += HandleLocationChanged;
        await LoadInitial();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // بارگذاری نرخ VAT
            await VAT.LoadAsync();
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    private async Task LoadInitial()
    {
        _loading = true;
        _currentPage = 1;
        _products.Clear();
        UpdateCategoryFilterFromUri();
        var sortBy = GetSortByValue();
        var result = await ProductService.GetProductsPagedAsync(_query, _activeCategoryId, sortBy, _currentPage, PageSize);
        _products = result.Products;
        _hasMore = result.HasNext;
        _totalCount = result.TotalCount;
        _activeCategoryTitle = _activeCategoryId is { } categoryId
            ? (await CategoryService.GetByIdAsync(categoryId))?.Title
            : null;
        _loading = false;
    }

    private async Task LoadMore()
    {
        if (_loadingMore || !_hasMore) return;
        
        _loadingMore = true;
        StateHasChanged();
        
        _currentPage++;
        var sortBy = GetSortByValue();
        var result = await ProductService.GetProductsPagedAsync(_query, _activeCategoryId, sortBy, _currentPage, PageSize);
        _products.AddRange(result.Products);
        _hasMore = result.HasNext;
        
        _loadingMore = false;
        StateHasChanged();
    }

    private string GetSortByValue()
    {
        return _sortOption switch
        {
            ProductSortOption.PriceDesc => "price desc",
            ProductSortOption.PriceAsc => "price asc",
            ProductSortOption.Newest => "id desc",
            ProductSortOption.Title => "title asc",
            _ => "price desc"
        };
    }

    private async Task OnSortChanged()
    {
        await LoadInitial();
    }

    private async Task OnQueryChanged(KeyboardEventArgs _)
    {
        await LoadInitial();
    }

    private async Task AddToCart(Product p)
    {
        await GuestGate.RunAsync(() => Cart.Add(p, 1));
    }

    private string FormatPrice(long price) => $"{VAT.AddVAT(price):N0} تومان";

    public void Dispose()
    {
        Cart.OnChange -= StateHasChanged;
        Navigation.LocationChanged -= HandleLocationChanged;
    }

    private void HandleLocationChanged(object? sender, LocationChangedEventArgs args)
    {
        _ = InvokeAsync(LoadInitial);
    }

    private void UpdateCategoryFilterFromUri()
    {
        var uri = Navigation.ToAbsoluteUri(Navigation.Uri);
        if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("category", out var values) &&
            long.TryParse(values.FirstOrDefault(), out var categoryId))
        {
            _activeCategoryId = categoryId;
            return;
        }

        _activeCategoryId = null;
    }

    private void ClearCategoryFilter()
    {
        Navigation.NavigateTo(RouteConstants.Store.Products);
    }
}
