import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import * as FileSaver from 'file-saver';
import { environment } from "../../environments/environment";
import { User } from "./user.model";

@Injectable({
  providedIn: "root"
})
export class UserService {
  selectedUser: User = {
    fullName: "",
    email: "",
    password: "",
    accountType: "",
    articles: [],
    search: [],
    click: [],
    feedback : []
  };

  noAuthHeader = { headers: new HttpHeaders({ NoAuth: "True" }) };

  constructor(private http: HttpClient) {}

  //HttpMethods
  search(data: any) {
    return this.http.post(environment.apiBaseUrl + "/search", data);
  }

  getArticle(data: any) {
    return this.http.post(environment.apiBaseUrl + "/getArticle", data);
  }
  
  //Creates user
  postUser(user: User) {
    return this.http.post(
      environment.apiBaseUrl + "/register",
      user,
      this.noAuthHeader
    );
  }

  //Use login
  login(authCredentials) {
    return this.http.post(
      environment.apiBaseUrl + "/authenticate",
      authCredentials,
      this.noAuthHeader
    );
  }

  //Returns user profile from MongoDB
  getUserProfile() {
    return this.http.get(environment.apiBaseUrl + "/userProfile");
  }
  
  //Updates profile information based on edit profile page
  updateProfile(data: any) {
    return this.http.post(
      environment.apiBaseUrl + "/updateProfile",
      data
    );
  }

  updateAccountType(data: any) {
    return this.http.post(
      environment.apiBaseUrl + "/updateAccountType",
      data
    );
  }

  //Saves article to databae
  addArticle(articleInfo: object) {
    return this.http.post(environment.apiBaseUrl + "/savearticle", articleInfo);
  }

  removeArticle(articleInfo: object) {
    return this.http.post(environment.apiBaseUrl + "/unsavearticle", articleInfo);
  }

  //adds click to prfile
  addClick(articleInfo: object) {
    return this.http.post(environment.apiBaseUrl + "/saveclick", articleInfo);
  }

  //Saves search history to databse
  saveSearch(search: object) {
    return this.http.post(environment.apiBaseUrl + "/savesearch", search);
  }

  question(answer: object) {
    return this.http.post(environment.apiBaseUrl + "/question", answer);
  }

  rating(rating: object) {
    return this.http.post(environment.apiBaseUrl + "/rating", rating);
  }

  getRating(article : object) {
    return this.http.post(environment.apiBaseUrl + "/getRating", article);
  }
  //Saves feedback history to DB
  addFeedback( feedbackInfo : object){
    return this.http.post(environment.apiBaseUrl + "/savefeedback", feedbackInfo);
  }

//save feedback entry
  saveEntries( entry : object){
    return this.http.post(environment.apiBaseUrl + "/saveEntries", entry);
  }
//saves click for dev stats
  saveClicks( entry : object){
    return this.http.post(environment.apiBaseUrl + "/saveClicks", entry);
  }

  //saves click for dev stats
  saveQueries( entry : object){
    return this.http.post(environment.apiBaseUrl + "/saveQueries", entry);
  }

  //saves click for dev stats
  getGlobalQuerySearches(data: object){
    return this.http.post(environment.apiBaseUrl + "/globalQuerySearches", data);
  }

  //saves click for dev stats
  getQuerySearchCount(){
    return this.http.get(environment.apiBaseUrl + "/countQuerySearches");
  }

  //returns the object with the date as a formatted string
  getObjectDate(data: object){
    return this.http.post(environment.apiBaseUrl + "/getObjectDate", data);
  }
  //Helper Methods

  //Sets login token
  setToken(token: string) {
    localStorage.setItem("token", token);
  }

  //Creates login token
  getToken() {
    return localStorage.getItem("token");
  }

  //Deletes login token
  deleteToken() {
    localStorage.removeItem("token");
  }

  //Used to get a user's token
  getUserPayload() {
    var token = this.getToken();
    if (token) {
      var userPayload = atob(token.split(".")[1]);
      return JSON.parse(userPayload);
    } else return null;
  }

  //Checks if user is logged in
  isLoggedIn() {
    var userPayload = this.getUserPayload();
    if (userPayload) {
      return userPayload.exp > Date.now() / 1000;
    } else return false;
  }

  //returns Account type
  getAccountType() {
    return this.http.get(environment.apiBaseUrl + "/userProfile");
  }

  // //Returns Feedback Interactions
  // getGlobalQuerySearches() {
  //   return this.http.get(environment.apiBaseUrl + "/feedbackInteractions");
  // }

  //Returns Feedback Interactions
  getFeedbackInteractions() {
    return this.http.get(environment.apiBaseUrl + "/feedbackInteractions");
  }

  //Returns Global Article Ratings
  getArticleRatings() {
    return this.http.get(environment.apiBaseUrl + "/articleRatings");
  }
  //returns Query Clicks
  getClicks(){
    return this.http.get(environment.apiBaseUrl + "/articleClicks");
  }


  //returns Query Clicks
  getQueryHistory(){

  }

  //returns Query Clicks
  updateQuerySearches(data: any){
      return this.http.post(environment.apiBaseUrl + "/updateQuerySearches", data);
  }

  //updates Global Query Clicks
  updateQueryArticleClicks(data: any){
      return this.http.post(environment.apiBaseUrl + "/updateQueryArticleClicks", data);
  }

  //updates Global Query Clicks
  updateQueryArticleFeedbacks(data: any){
      return this.http.post(environment.apiBaseUrl + "/updateQueryArticleFeedbacks", data);
  }

  updateArticleInfoClicks(data: any) {
    return this.http.post(environment.apiBaseUrl + "/updateArticleInfoClicks", data);
  }

  updateArticleInfoRating(data: any) {
    return this.http.post(environment.apiBaseUrl + "/updateArticleInfoRating", data);
  }

  getArticleInfoProperties(data: any) {
    return this.http.post(environment.apiBaseUrl + "/getArticleInfoProperties", data);
  }
  
  //saves click for dev stats
  getAllGlobalProperties(data: any){
      return this.http.post(environment.apiBaseUrl + "/globalProperties", data);
  }

  //HttpMethods
  mergeByKey(data: any) {
    return this.http.post(environment.apiBaseUrl + "/mergeByKey", data);
  }

  downloadTable(data: any, tableName: string) {
    const replacer = (key, value) => value === null ? 0 : value; 
    const header = Object.keys(data[0]);
    let csv = data.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','));
    csv.unshift(header.join(','));
    let csvArray = csv.join('\r\n');

    var blob = new Blob([csvArray], {type: 'text/csv' })
    FileSaver.saveAs(blob, tableName + ".csv");
  }
}
