using Insight.Web.Constants;
using Insight.Web.Extensions;
using Microsoft.AspNetCore.Components;
using MudBlazor;

namespace Insight.Web.Components.Containers;

public partial class TableContainer<T>
{
    [Inject] private NavigationManager NavigationManager { get; init; } = default!;


    [Parameter]
    public string Title { get; set; } = Global.Name;

    [Parameter]
    public List<BreadcrumbItem>? Breadcrumbs { get; set; }

    [Parameter]
    public Func<TableState, Task<TableData<T>>>? Data { get; set; }

    [Parameter]
    public RenderFragment? Header { get; set; }

    [Parameter]
    public RenderFragment<T>? RowTemplate { get; set; }

    [Parameter]
    public RenderFragment<T>? ActionTemplate { get; set; }

    [Parameter]
    public bool DisableAction { get; set; }


    private List<BreadcrumbItem>? AddBreadcrumbs { get; set; }
    private MudTable<T>? Table { get; set; }
    private bool Loading { get; set; }

    private int CurrentPage { get; set; }
    private int CurrentSize { get; set; }

    protected override void OnInitialized()
    {
        if (OnAdd.HasDelegate)
        {
            AddBreadcrumbs = new List<BreadcrumbItem>()
            {
                new BreadcrumbItem("", "#", true),
                new BreadcrumbItem("", "#", true)
            };
        }

        if (NavigationManager.GetQueryString().TryGetValue("search", out var search))
        {
            Search = search.ToString();
        }

        //if (NavigationManager.GetQueryString().TryGetValue("page", out var pageRaw))
        //{
        //    if (int.TryParse(pageRaw, out var page))
        //    {
        //        CurrentPage = page;
        //    }
        //}

        //if (NavigationManager.GetQueryString().TryGetValue("size", out var sizeRaw))
        //{
        //    if (int.TryParse(sizeRaw, out var size))
        //    {
        //        CurrentSize = size == 0 ? 100 : size;
        //    }
        //}
    }

    private async Task<TableData<T>> OnLoadDataAsync(TableState state)
    {
        if (Data is null)
        {
            throw new MissingMethodException(nameof(Data));
        }

        try
        {
            Loading = true;

            //state.Page = CurrentPage;
            //Table.SetRowsPerPage(CurrentSize);

            var data = await Data(state);

            //CurrentPage = state.Page;
            //CurrentSize = state.PageSize;

            //NavigationManager.ChangeQueryStringValue("page", state.Page.ToString());
            //NavigationManager.ChangeQueryStringValue("size", state.PageSize.ToString());

            //if (state.SortLabel is not null) NavigationManager.ChangeQueryStringValue("sort", state.SortLabel.ToString());
            //if (state.SortDirection) NavigationManager.ChangeQueryStringValue("direction", state.SortDirection.ToString());

            return data;
        }
        finally
        {
            Loading = false;
        }
    }

    //

    [Parameter]
    public bool DisableRefresh { get; set; }

    private string? _search;

    [Parameter]
    public string? Search
    {
        get => _search;
        set
        {
            if (_search == value) return;
            _search = value;

            SearchChanged.InvokeAsync(value);
        }
    }

    [Parameter]
    public EventCallback<string?> SearchChanged { get; set; }

    private async Task SearchAsync(string? text)
    {
        Search = text;

        if (Loading) return;
        await RefreshAsync();
    }

    public async Task RefreshAsync()
    {
        if (Loading || Table is null) return;

        Loading = true;
        StateHasChanged();

        //var start = Stopwatch.GetTimestamp();

        await Table.ReloadServerData();

        //var time = Stopwatch.GetElapsedTime(start);

        //if (time <= TimeSpan.FromSeconds(1))
        //{
        //    await Task.Delay(TimeSpan.FromSeconds(1).Subtract(time));
        //}

        Loading = false;
        StateHasChanged();
    }

    private void OnSearchReleased()
    {
        NavigationManager.ChangeQueryStringValue("search", Search);
    }

    //

    [Parameter] public EventCallback OnFilter { get; set; }


    [Parameter]
    public bool Filtered { get; set; }

    private async Task OnFilterClick()
    {
        if (OnFilter.HasDelegate)
        {
            await OnFilter.InvokeAsync(this);
        }
    }

    //

    [Parameter]
    public EventCallback OnAdd { get; set; }

    private async Task OnAddClick()
    {
        if (OnAdd.HasDelegate)
        {
            await OnAdd.InvokeAsync(this);
        }
    }
}