# Source: src/js/views/search/SearchResultsView.js

    /*global define */
    define(["backbone",
            "collections/SolrResults",
            "views/search/SearchResultView"
        ],
    function(Backbone, SearchResults, SearchResultView){

        "use strict";

        /**
        * @class SearchResultsView
        * @name SearchResultsView
        * @classcategory Views/Search
        * @extends Backbone.View
        * @since 2.22.0
        * @constructor
        */
        return Backbone.View.extend(
          /** @lends SearchResultsView.prototype */ {

        /**
        * The type of View this is
        * @type {string}
        */
        type: "SearchResults",

        /**
        * The HTML tag to use for this view's element
        * @type {string}
        */
        tagName: "div",

        /**
        * The HTML classes to use for this view's element
        * @type {string}
        */
        className: "search-results-view",

         /**
        * The events this view will listen to and the associated function to call.
        * @type {Object}
        */
        events: {
        },

        /**
         * The SolrResults collection that fetches and parses the searches.
         * @type {SolrResults}
         */
        searchResults: null,

        /**
         * The HTML to display when no search results are found.
         * @since 2.22.0
         * @type {string}
         */
        noResultsTemplate: `<div class="no-search-results">No results found.</div>`,

        render: function(){

          if( !this.searchResults ){
            this.setSearchResults();
          }

          this.loading();

          this.addResultCollection();

          this.startListening();

        },

        /**
         * Sets listeners on the {@link SearchResultsView#searchResults} to change what is displayed in this view.
         */
        startListening: function(){
          this.listenTo(this.searchResults, "add", this.addResultModel);
          this.listenTo(this.searchResults, "reset", this.addResultCollection);
          this.listenTo(this.searchResults, "request", this.loading);
        },

        /**
         * Creates and sets the {@link SearchResultsView#searchResults} property.
         * @returns {SolrResults}
         */
        setSearchResults: function(){
          this.searchResults = new SearchResults();
          return this.searchResults;
        },

        /**
         * Renders the given {@link SolrResult} model inside this view.
         * @param {SolrResult} searchResult
         */
        addResultModel: function(searchResult){
          try{
            let view = this.createSearchResultView();
            view.model = searchResult;
            this.addResultView(view);
          }
          catch(e){
            console.error("Failed to add a search result to the page: ", e);
          }
        },

        /**
         * Renders all {@link SolrResult}s from the {@link SearchResultsView#searchResults} collection.
         */
        addResultCollection: function(){
          if( !this.searchResults )
            return;
          else if( this.searchResults?.header?.get("numFound") == 0){
            this.showNoResults();
            return;
          }

          this.empty();

          this.searchResults.models.forEach( result => {
            this.addResultModel(result);
          });
        },

        /**
         * Adds a Search Result View to the page
         * @param {SearchResultView} view
         */
        addResultView: function(view) {
          this.el.append(view.el);
          view.render();
        },

        /**
         * Creates a Search Result View
        */
        createSearchResultView: function(){
          return new SearchResultView();
        },

        /**
         * Shows a message when no search results have been found.
         */
        showNoResults: function(){

          this.empty();

          this.el.replaceChildren(this.noResultsTemplate);

        },

        empty: function(){
          this.el.innerHTML = "";
        },

        /**
         * Renders a skeleton of this view that communicates to the user that it is loading.
         */
        loading: function(){

          this.empty();

          let rows = this.searchResults.rows,
              i=0;

          while(i < rows){
            let view = this.createSearchResultView();
            this.addResultView(view);
            view.loading();
            i++;
          }

        }

        });

    });