@inherits BasePage
@page "/database"
@using Model
@implements IDisposable

@inject IEntityDisplayService EntityDisplayService


<LayoutLargeContentComponent>
    <WebsiteTitleComponent>Database</WebsiteTitleComponent>

    <PaperComponent>
        <FormDisplayComponent Label="Patch">
            <Display>
                Game Patch: @Variables.GamePatch
            </Display>
        </FormDisplayComponent>
    </PaperComponent>

    <div style="margin-left: 8px">
        <ButtonGroupComponent OnClick="choice => { EntityDisplayService.SetDisplayType(choice); }"
                              Choice="@EntityDisplayService.GetDisplayType()"
                              Choices="@EntityDisplayService.DefaultChoices()"></ButtonGroupComponent>
    </div>

    <PaperComponent>
        <EntityFilterComponent></EntityFilterComponent>

        @if (searches != null)
        {
            <div class="databaseItems">
                @foreach (var entity in searches)
                {
                    <CascadingValue Value="entity">
                        <CascadingValue Value="@EntityDisplayService.GetDisplayType()">
                            <EntityViewComponent></EntityViewComponent>
                        </CascadingValue>
                    </CascadingValue>
                }
            </div>
        }
    </PaperComponent>


    <ContentDividerComponent></ContentDividerComponent>

    <PaperComponent>
        <InfoBodyComponent>
            <InfoQuestionComponent>
                What is this tool?
            </InfoQuestionComponent>
            <InfoAnswerComponent>
                This is a reference database. Mostly so unit stats can be reviewed outside of the game, IMMORTAL: Gates
                of Pyre.
            </InfoAnswerComponent>
        </InfoBodyComponent>

        <InfoBodyComponent>
            <InfoQuestionComponent>
                Is this database complete?
            </InfoQuestionComponent>
            <InfoAnswerComponent>
                No. A lot of content is missing, that needs to be manually transfered from screenshots of IMMORTAL:
                Gates of Pyre. This will happen slowly over-time.
            </InfoAnswerComponent>
        </InfoBodyComponent>

        <InfoBodyComponent>
            <InfoQuestionComponent>
                Is this database updated to the latest version?
            </InfoQuestionComponent>
            <InfoAnswerComponent>
                Maybe. Check this <b>@Variables.GamePatch</b> version number, and compare it to the
                number on discord, in the <b>#game-updates</b> channel. That should give a general sense of how out of
                date the data is.
            </InfoAnswerComponent>
        </InfoBodyComponent>

        <InfoBodyComponent>
            <InfoQuestionComponent>
                This database has some errors in it.
            </InfoQuestionComponent>
            <InfoAnswerComponent>
                Yup. The content is being transferred by hand, so some mistakes are expected.
            </InfoAnswerComponent>
        </InfoBodyComponent>
    </PaperComponent>
</LayoutLargeContentComponent>

<style>
    .databaseItems {
        height: 900px;
        overflow-x: hidden;
        overflow-y: auto;
        background-color: var(--background);
        gap: 4px;
        border-top: 4px solid var(--accent);
        border-bottom: 4px solid var(--accent);
        padding: 4px;
    }

    .databaseInfoContainer {
        display: flex;
        gap: 24px;

    }

</style>


@code {

    [Inject] public IEntityFilterService EntityFilterService { get; set; } = default!;

    readonly List<EntityModel> defaults = (from entity in EntityModel.GetList()
        where !entity.IsSpeculative
        select entity).ToList();

    List<EntityModel> factions = default!;
    List<EntityModel> immortals = default!;
    List<EntityModel> entities = default!;
    List<EntityModel> searches = default!;


    string selectedFactionType = DataType.Any;
    string selectedImmortalType = DataType.Any;
    string selectedEntityType = EntityType.Army;
    string searchText = "";

    protected override void OnInitialized()
    {
        base.OnInitialized();
        RefreshFactionSearch();

        EntityFilterService.Subscribe(OnChange);
        EntityDisplayService.Subscribe(StateHasChanged);
    }

    void IDisposable.Dispose()
    {
        EntityFilterService.Unsubscribe(OnChange);
        EntityDisplayService.Unsubscribe(StateHasChanged);
    }

    void OnChange(EntityFilterEvent filterEntityEvent)
    {
        if (filterEntityEvent == EntityFilterEvent.OnRefreshFaction)
        {
            RefreshFactionSearch();
        }

        if (filterEntityEvent == EntityFilterEvent.OnRefreshImmortal)
        {
            RefreshImmortalSearch();
        }

        if (filterEntityEvent == EntityFilterEvent.OnRefreshEntity)
        {
            RefreshEntitySearch();
        }


        if (filterEntityEvent == EntityFilterEvent.OnRefreshSearch)
        {
            RefreshTextSearch();
        }
    }

    void RefreshFactionSearch()
    {
        selectedFactionType = EntityFilterService.GetFactionType();

        if (selectedFactionType == DataType.Any)
        {
            factions = defaults.ToList();
        }
        else
        {
            factions = (from entity in defaults
                where entity.Faction() != null && entity.Faction().Faction == selectedFactionType
                select entity).ToList();
        }

        RefreshImmortalSearch();
    }


    void OnImmortalChanged(ChangeEventArgs e)
    {
        selectedImmortalType = e.Value!.ToString()!;
        RefreshImmortalSearch();
    }

    void RefreshImmortalSearch()
    {
        selectedImmortalType = EntityFilterService.GetImmortalType();

        if (selectedImmortalType == DataType.Any)
        {
            immortals = factions.ToList();
        }
        else
        {
            immortals = (from entity in factions
                where entity.VanguardAdded() == null || entity.VanguardAdded().ImmortalId == selectedImmortalType
                select entity).ToList();
        }

        RefreshEntitySearch();
    }

    void OnEntityChanged(ChangeEventArgs e)
    {
        selectedEntityType = e.Value!.ToString()!;
        RefreshEntitySearch();
    }

    void RefreshEntitySearch()
    {
        selectedEntityType = EntityFilterService.GetEntityType();

        if (selectedEntityType == EntityType.Any)
        {
            entities = immortals.ToList();
        }
        else
        {
            entities = (from entity in immortals
                where entity.EntityType == selectedEntityType
                select entity).ToList();
        }

        RefreshTextSearch();
    }

    void OnSearchTextChanged(ChangeEventArgs e)
    {
        searchText = e.Value!.ToString()!;
        RefreshTextSearch();
    }

    void RefreshTextSearch()
    {
        searchText = EntityFilterService.GetSearchText();

        if (searchText.Trim() == "")
        {
            searches = entities.ToList();
        }
        else
        {
            searches = (from entity in entities
                where entity.Info().Name.ToLower().Contains(searchText.ToLower())
                select entity).ToList();
        }

        StateHasChanged();
    }

}