import { Component, OnInit } from "@angular/core";
import { Router, NavigationExtras } from "@angular/router";
import * as $ from "jquery";
import { UserService } from "../../shared/user.service";

@Component({
  selector: "app-displayresults",
  templateUrl: "./displayresults.component.html",
  styleUrls: ["./displayresults.component.css"]
})
export class DisplayresultsComponent implements OnInit {
  
  //=============Inialize Variables=============//
  response: any;
  //list of articles after date filter in getDate()
  editedResponse: any;
  //articles sent to user on results page
  finalResponse: any;

  minimumYear: number = 1900;
  maximumYear: number = 2019;
  x: number = 0;
  numArticles: number = 9900;
  query: string = window.location.search.substring(1).split("=")[1];
  specifyWebsite: number;
  userDetails;
  feedBackDetails;
  globalProperties;
  globalPropertyTuple : any = {"article_clicks" : 0, 
                              "feedback_interactions": 0};
  sortBy;

  pageSize: number = 10;
  currentPage: number = 0;
  sortingBy: string = null;
  filterDates: string = null;

  totalItems: number;
  timeTook: number;

  constructor(
    private router: Router,
    public userService: UserService
  ) {}

  //=======================WHEN PAGE LOADS=======================//
  ngOnInit() {
    // var query: string = window.location.search.substring(1).split("=")[1];
    var query: string = window.location.search.slice(1);
    this.sortBy = { sortBy: "query_searches"};

    //URL parameters stored here
    var paramObj = {};
    if(query) {
      //everything after # is not part of our query string, so remove it
      query = query.split('#')[0];
      
      //split our query into its component parts
      var arr = query.split('&');
      
      for(var i = 0; i < arr.length; i++) {
        // separate all keys and values
        var a = arr[i].split('=');

        var paramName = a[0];
        var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];
        //if doesn't exist, create property
        if(!paramObj[paramName]) {
          paramObj[paramName] = paramValue;
        } else if (paramObj[paramName] && typeof paramObj[paramName] === 'string'){
          // if property does exist and it's a string, convert it to an array
          paramObj[paramName] = [paramObj[paramName]];
          paramObj[paramName].push(paramValue);
        } else {
          // otherwise add the property
          paramObj[paramName].push(paramValue);
        }
      }
    }

    this.query = paramObj["search"];

    if(paramObj.hasOwnProperty("sortby")) {
      this.sortingBy = paramObj["sortby"];
    }

    if(paramObj.hasOwnProperty("dates")) {
      this.filterDates = paramObj["dates"];
    }

    if(paramObj.hasOwnProperty("size")) {
      this.pageSize = paramObj["size"];
    }

    var spacedQuery: string = paramObj["search"].replace(/%20/gi, " ");

    if (this.userService.isLoggedIn()) {
      var searchHistory = {
        search: { spacedQuery }
      };

      this.userService.getUserProfile().subscribe(
        res => {
          this.userDetails = res["user"];
          this.userService.saveSearch(searchHistory).subscribe();

        },
        err => {}
      );
      var user = "User";//calling this.usertDetail.email breaks search
    }
      else {
        user = "anonymous";
      }

      this.userService.getAllGlobalProperties(this.sortBy).subscribe(
        res => {
          this.globalProperties = res["globalProperties"];
          
          for(let globalProperty of this.globalProperties) {
            if(globalProperty.search_query == this.query) {
              this.globalPropertyTuple = { "article_clicks" : globalProperty.article_clicks, 
                                            "feedback_interactions": globalProperty.feedback_interactions};
            }
          }

          var entry =  {
            search_query: spacedQuery,
            user: user,
            article_clicks: this.globalPropertyTuple.article_clicks,
            feedback_interactions: this.globalPropertyTuple.feedback_interactions,
            interaction_type: "search"
          };
          this.userService.saveQueries(entry).subscribe();
          //update global amount of query searches for this query for DevStats
          this.userService.updateQuerySearches(entry).subscribe();
      
          this.search(paramObj);
        },
        err => {}
      );

  }

  //========================PULL SEARCH RESULTS FROM DATABASE========================//
  /**
   * This function is called whenever a user types a search query in either the homepage
   * or the display results page. It will use an HTTP GET request to the JSON file containing
   * all the article information. The displayresults.component.html file will use interpolation
   * to show the results
   */
  search(paramObj) {
    var entry =  {
      page: paramObj["page"],
      sortBy: paramObj["sortby"],
      dates: paramObj["dates"],
      size: paramObj["size"],
      query: this.query,
      numArticles: this.numArticles,
    };

    this.currentPage = paramObj["page"];

    if(this.filterDates!=null){
      this.minimumYear = +((paramObj["dates"]).split("-",2))[0];
      this.maximumYear = +((paramObj["dates"]).split("-",2))[1];
      }

    this.userService.search(entry).subscribe(
      res => {
        this.response = res;
        this.timeTook = this.response.took;

        //if there are too many articles, set the max amount to numArticcles
        if(this.response.hits.total >= 9990) {
          this.totalItems = this.numArticles;  

        } else {
          this.totalItems = this.response.hits.total;
        }
      },
      err => {}
    );
  }

  website(specifyWebsite) {
    if (specifyWebsite == 0) {
      if (confirm("You are about to be directed to academic.microsoft.com."))
        window.open(
          "https://academic.microsoft.com/#/search?iq=%40" +
            this.query +
            "%40&q=" +
            this.query +
            "&filters=Y>%3D" +
            this.minimumYear +
            "%2CY<%3D" +
            this.maximumYear +
            "&from=0&sort=0",
          "_blank"
        );
    } else {
      if (confirm("You are about to be directed to semanticscholar.com."))
        if (this.filterDates != null)
          window.open(
            "https://www.semanticscholar.org/search?year%5B0%5D=" +
              this.minimumYear +
              "&year%5B1%5D=" +
              this.maximumYear +
              "&q=" +
              this.query +
              "&sort=relevance",
            "_blank"
          );
        else
          window.open(
            "https://www.semanticscholar.org/search?q=" +
              this.query +
              "&sort=relevance",
            "_blank"
          );
    }
  }

  //========================CONCEPTS========================//
  /**
   * This function is called whenever a user clicks on a concept that they wish to add to
   * enhance their search. It will replace the search in the url with the concept and load
   * the page with that concept.
   */
  public addConcept(index: number) {
    window.location.href =
      "./displayresults?search=" +
      this.response.hits.hits[index]._source.keywords[0].keyword + "&page=1";
  }

  /**
   *
   * This function gets called when a user submits a search on the display
   * results
   * It will redirect to the displayresults page with the search query entered
   */
  sortByRecent() {
    var reqURI = "./displayresults?search=" + this.query + "&page=1" + "&sortby=most_recent";

    if(this.filterDates != null) {
      reqURI = reqURI + "&dates=" + this.filterDates;
    } 

    if(this.pageSize != 10) {
      reqURI = reqURI + "&size=" + this.pageSize;
    }

    this.sortingBy = "most_recent";

    window.location.href = reqURI;
  }

  /**
   * This function gets called when a user submits a search on the display
   * results
   * It will redirect to the displayresults page with the search query entered
   */
  sortByRelevance() {
    var reqURI = "./displayresults?search=" + this.query + "&page=1" + "&sortby=relevance";

    if(this.filterDates != null) {
      reqURI = reqURI + "&dates=" + this.filterDates;
    } 

    if(this.pageSize != 10) {
      reqURI = reqURI + "&size=" + this.pageSize;
    }

    this.sortingBy = "relevance";

    window.location.href = reqURI;
  }

  //====================CITE====================//
  /**
   * This function is called when the user clicks on Cite. It will create a popup box
   * with the citation for the article.
   */
  toggle_cite(id) {
    var e = document.getElementById(id);
    if (e.style.display == "block") {
      e.style.display = "none";
    } else {
      e.style.display = "block";
    }
  }

  // //=================DATE FILTER=================//
  // //Filter by date range, specify min year and max year
  goToFilteredDates(minYear, maxYear) {
    
    this.filterDates = minYear + "-" + maxYear;
    
    var reqURI = "./displayresults?search=" + this.query + "&page=1" + "&dates=" + this.filterDates;

    if(this.sortingBy != null) {
      reqURI = reqURI + "&sortby=" + this.sortingBy;
    } 

    if(this.pageSize != 10) {
      reqURI = reqURI + "&size=" + this.pageSize;
    } 


    window.location.href = reqURI;

  }
  //Checks if the entered range is allowed
  checkDateRange(year) {
    if ((year < 1900 || year > 2019) && year != "" && year != null) {
      alert("Year: '" + year + "' is out of range");
    }
  }

    /**
   *
   * This function gets called when a user changes the page size from the filter
   * options. It redirects the user to a page that includes the page size,
   * making sure to keep the current filter state.
   */
  changePageSize(size) {
    var reqURI = "./displayresults?search=" + this.query + "&page=1" + "&size=" + size;

    if(this.filterDates != null) {
      reqURI = reqURI + "&dates=" + this.filterDates;
    }

    if(this.sortingBy != null) {
      reqURI = reqURI + "&sortby=" + this.sortingBy;
    }

    window.location.href = reqURI;

  }
  //Checks if the entered page size is allowed
  checkPageSize(size) {
    if ((size < 1 || size > 10) && size != "" && size != null) {
      alert("Size: '" + size + "' is out of range");
    }
  }

  //==================CLEAR FILTER==================//
  clearFilters() {
    window.location.href =
      "./displayresults?search=" + this.query + "&page=1";
  }
  

/**
   *
   * This function gets called when a user clicks on a new page number.
   * options. It redirects the user to a page that includes the page number,
   * making sure to keep the current filter state.
*/
  goToPage(p: number) {
    var queryURI = "./displayresults?search=" + this.query + "&page=" + p;

    if(this.sortingBy != null) {
      queryURI = queryURI + "&sortby=" + this.sortingBy;
    }

    if(this.filterDates != null) {
      queryURI = queryURI + "&dates=" + this.filterDates;
    }

    window.location.href = queryURI;
  }
  //=======================ARTICLE=======================//
  /**
   * This function is called when a user clicks on an article link in display results. It sets the article index to the article_info to be called in the articleinfo
   */
  navigate(i: number) {
  if (this.userService.isLoggedIn()) {
      var article_id = this.response.hits.hits[i]._source.article_id;
      var title = this.response.hits.hits[i]._source.title;
      var authors = this.response.hits.hits[i]._source.authors;
      var year = this.response.hits.hits[i]._source.cover_date;
      var abstract = this.response.hits.hits[i]._source.abstract;
      var spacedQuery: string = this.query.replace(/%20/gi, " ");
      var article_url = this.response.hits.hits[i]._source.url;
      var clickInfo = {
        click: {article_id, title, authors, year, abstract, spacedQuery, article_url}
      };

      this.userService.getUserProfile().subscribe(
        res => {
          this.userDetails = res["user"];
          this.userService.addClick(clickInfo).subscribe();

        },
        err => {}
      );
      var user = this.userDetails.email;
    }else{ user = "anonymous";}

    var query1: string = this.query;
    var search: string = query1.replace(/%20/gi, " ");
    // click entry
    var entry =  {
      article_id: article_id,
      title: title,
      search_query: search,
      user: user,
      clicks : 1
    };
    this.userService.saveClicks(entry).subscribe();
    //update global amount of query clicks for this query for DevStats
    this.userService.updateQueryArticleClicks(entry).subscribe();
    this.userService.updateArticleInfoClicks(entry).subscribe();
    let navigationExtras: NavigationExtras = {
      queryParams: {
        article_id: this.response.hits.hits[i]._source.article_id
      }
    };

    this.router.navigate(["article"], navigationExtras);
  }

  //Click Article Website to open the link on a new page
  articleURL(url: string) {
    window.open(url, "_blank");
  }

  //This function is called when the user clicks the Save link
  //It will get the article information and put it into an object to
  //then send over through the addArticle() function
  saveArticle(
    article_id: number,
    title: string,
    authors: Array<string>,
    year: string,
    abstract: string,
    article_url: string
  ) {
    var articleInfo = {
      articles: {article_id, title, authors, year, abstract,article_url }
    };
    this.userService.getUserProfile().subscribe(
      res => {
        this.userDetails = res["user"];
        this.userService.addArticle(articleInfo).subscribe();
        document.getElementById(title).innerHTML = "Saved!";
      },
      err => {}
    );
  }

  //This function is called when the user clicks the unSave link
  //It will get the article information and put it into an object to
  //then send over through the removeArticle() function
  unsaveArticle(
    article_id: number,
    title: string,
    authors: Array<string>,
    year: string,
    abstract: string,
    article_url:string
  ) {
    var articleInfo = {
      articles: {article_id, title, authors, year, abstract,article_url }
    };
    this.userService.getUserProfile().subscribe(
      res => {
        this.userDetails = res["user"];
        this.userService.removeArticle(articleInfo).subscribe();
        document.getElementById(title).innerHTML = "Unsaved!";

      },
      err => {}
    );
  }

 //Opens Save popup
  save_success(id) {
    var e = document.getElementById(id);
    if (e.style.display == "block") {
      e.style.display = "none";
    } else {
      e.style.display = "block";
    }
  }

  //Opens the Share popup
  share(id) {
    var e = document.getElementById(id);
    if (e.style.display == "block") {
      e.style.display = "none";
    } else {
      e.style.display = "block";
    }
  }

  //============FEEDBACK============//
  feedback() {
    var question1 = prompt("How do you like the website?", "I love it!");
    var question2 = prompt("Rate your experience: 1-10", "10");
    /*if (!this.userService.isLoggedIn()) {
      this.router.navigateByUrl("/login");
    };*/
    var answer1 = {
      question: { question1, question2 }
    };

    this.userService.question(answer1).subscribe();
  }

  //=========ARTICLE FEEDBACK===============//

  //====Mark as relevant=======//
  relevant(article_id: number, title : string, authors: Array<string>, year: string, abstract: string) {

    var article =  {
      title: title
    };
    //===============================individual feedback entry=======//

    if (this.userService.isLoggedIn()){
      this.userService.getUserProfile().subscribe(
        res => {
          this.userDetails = res["user"];
        });
      var user = this.userDetails.email;
    } else{ user = "anonymous";}

    var query1: string = this.query;
    var search: string = query1.replace(/%20/gi, " ");
    // feedback entry
    var entry =  {
      article_id: article_id,
      title: title,
      search_query: search,
      user: user,
      rating : 1
    };

    if(document.getElementById(title+'-relevant').innerHTML =="Relevant") {
      //upvote global amount of query feedbacks for this query for DevStats
      this.userService.updateQueryArticleFeedbacks(entry).subscribe();
      this.userService.updateArticleInfoRating(entry).subscribe();
      this.userService.saveEntries(entry).subscribe();
    }

    document.getElementById(title+'-relevant').innerHTML = "Marked!";


      


//=============================================
    if (this.userService.isLoggedIn()){
    var rate =1;
    var feedbackInfo =  {
      feedback:{ title, authors,year,abstract, rate}
    };


    /*saves feedback history to users profile*/
  this.userService.getUserProfile().subscribe(
  res => {
  
    if(document.getElementById(title+'-relevant').innerHTML =="Relevant") {
      this.userDetails = res["user"];
      this.userService.addFeedback(feedbackInfo).subscribe();
    }

  },
  err => {}
);
    }

/*saves feedback and keeps total rating for an article. Increases rating*/
    this.userService.getRating(article).subscribe(
      res => {
        this.feedBackDetails = res["articlefeedback"];
         this.feedBackDetails;
        var currentRating = this.feedBackDetails.rating;
        const rating1 = {
          rating: currentRating + 1,
          title: title
      };
        this.userService.rating(rating1).subscribe();
          document.getElementById(title+'-relevant').innerHTML = "Marked!";

      },
      err => {}
    );


  }


  //checks if article is saved 
  isSaved(i: number){
    if (this.userService.isLoggedIn()) {
      var article_id = this.response.hits.hits[i]._source.article_id;
       for (var articles of this.userDetails.articles ) {
       if (article_id== articles.article_id) return true;
      
       }

    }
  }

  //============TEST TO CONSOLE============//
  toConsole() {}
}
