using Model.Entity.Data;
using Model.Glossary;
using Model.Website;
using Model.Website.Data;

namespace Services.Website;

public class SearchService : ISearchService
{
    private readonly INoteService noteService;

    private bool isLoaded;

    public SearchService(INoteService noteService)
    {
        this.noteService = noteService;
    }

    public List<SearchPointModel> SearchPoints { get; set; } = new();

    public Dictionary<string, List<SearchPointModel>> Searches { get; set; } = new();

    public bool IsVisible { get; set; }

    public void Subscribe(Action action)
    {
        OnChange += action;
    }

    public void Unsubscribe(Action action)
    {
        OnChange += action;
    }

    public void Search(string entityId)
    {
    }

    public async Task Load()
    {
        await noteService.Load();


        Searches.Add("Pages", new List<SearchPointModel>());
        Searches.Add("Notes", new List<SearchPointModel>());
        Searches.Add("Entities", new List<SearchPointModel>());
        Searches.Add("Glossary", new List<SearchPointModel>());

        foreach (var webPage in WebsiteData.GetPages())
        {
            SearchPoints.Add(new SearchPointModel
            {
                Title = webPage.Name,
                PointType = "WebPage",
                Summary = $"{webPage.Description}",
                Href = webPage.Href
            });

            Searches["Pages"].Add(SearchPoints.Last());
        }

        foreach (var note in noteService.NoteContentModels)
        {
            SearchPoints.Add(new SearchPointModel
            {
                Title = note.Name,
                PointType = "Note",
                Href = note.GetNoteLink(),
                Summary = note.Description
            });

            Searches["Notes"].Add(SearchPoints.Last());
        }


        foreach (var entity in EntityData.Get().Values)
        {
            var summary =
                entity.Info().Description.Length > 35
                    ? entity.Info().Description.Substring(0, 30).Trim() + "..."
                    : entity.Info().Description.Length > 0
                        ? entity.Info().Description
                        : "";

            SearchPoints.Add(new SearchPointModel
            {
                Title = entity.Info().Name,
                Tags = $"{entity.EntityType},{entity.Descriptive}",
                PointType = "Entity",
                Summary = $"{entity.EntityType}, {summary}",
                Href = $"database/{entity.Info().Name.ToLower()}"
            });

            Searches["Entities"].Add(SearchPoints.Last());
        }

        if (WebsiteData.allowSlopData)
            foreach (var term in GlossaryData.GetTerms().Values)
            {
                SearchPoints.Add(new SearchPointModel
                {
                    Title = term.Term,
                    PointType = "Glossary",
                    Summary = term.ShortDefinition,
                    Href = $"glossary/{term.Id}"
                });

                Searches["Glossary"].Add(SearchPoints.Last());
            }

        isLoaded = true;

        NotifyDataChanged();
    }

    public bool IsLoaded()
    {
        return isLoaded;
    }

    public void Show()
    {
        IsVisible = true;

        NotifyDataChanged();
    }

    public void Hide()
    {
        IsVisible = false;

        NotifyDataChanged();
    }

    private event Action OnChange = null!;

    private void NotifyDataChanged()
    {
        OnChange();
    }
}