using System.Text;

namespace OpenArchival.DataAccess;

public static class ArtifactGroupingExtensions
{
    /// <summary>
    /// Concatinates all data that can be searched on into large strings so that Postgres can turn them into search vectors
    /// </summary>
    /// <param name="grouping"></param>
    public static void GenerateSearchIndex(this ArtifactGrouping grouping)
    {
        var allSearchSb = new StringBuilder();
        var tagsSb = new StringBuilder();
        var defectsSb = new StringBuilder();
        var listedNamesSb = new StringBuilder();
        var titlesSb = new StringBuilder();
        var descriptionsSb = new StringBuilder();
        var filenamesSb = new StringBuilder();
        var fileContentSb = new StringBuilder();

        // Put all the top level data in
        allSearchSb.Append($"{grouping.Title} ");
        titlesSb.Append($"{grouping.Title} ");

        allSearchSb.Append($"{grouping.Description} ");
        descriptionsSb.Append($"{grouping.Description} ");

        foreach (ArtifactEntry entry in grouping.ChildArtifactEntries)
        {
            allSearchSb.Append($"{entry.Title} ");
            titlesSb.Append($"{entry.Title} ");

            allSearchSb.Append($"{entry.Description} ");
            descriptionsSb.Append($"{entry.Description} ");

            foreach (ArtifactEntryTag tag in entry.Tags)
            {
                allSearchSb.Append($"{tag.Name} ");
                tagsSb.Append($"{tag.Name} ");
            }

            if (entry.Defects is not null) {
                foreach (ArtifactDefect defect in entry.Defects)
                {
                    allSearchSb.Append($"{defect.Description} ");
                    defectsSb.Append($"{defect.Description} ");
                }
            }

            if (entry.ListedNames is not null)
            {
                foreach (ListedName name in entry.ListedNames)
                {
                    allSearchSb.Append($"{name.Value} ");
                    listedNamesSb.Append($"{name.Value} ");
                }
            }

            foreach (FilePathListing file in entry.Files)
            {
                allSearchSb.Append($"{file.OriginalName} ");
                filenamesSb.Append($"{file.OriginalName} ");
            }

            fileContentSb.Append($"{entry.FileTextContent} ");
            allSearchSb.Append($"{entry.FileTextContent} ");
        }

        grouping.AllSearchString = allSearchSb.ToString();
        grouping.TagsSearchString = tagsSb.ToString();
        grouping.DefectsSearchString = defectsSb.ToString();
        grouping.ListedNamesSearchString = listedNamesSb.ToString();
        grouping.TitleSearchString = titlesSb.ToString();
        grouping.DescriptionSearchString = descriptionsSb.ToString();
        grouping.FilenamesSearchString = filenamesSb.ToString();
    }
}

