import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils";


export class User {
  email: string;
  firstname: string;
  lastname: string;
  id: string;
  fullname: string;
  expirationDate: number;
  role: string[];
  accessToken?: string;
  orcid?: string;
  refreshToken?: string;

  constructor(info: any) {
    this.id = (info.sub && info.sub.indexOf('@')) ? info.sub.substring(0, info.sub.indexOf('@')) : info.sub;
    this.firstname = (info.given_name) ? info.given_name : "";
    this.lastname = (info.family_name) ? info.family_name : "";
    this.email = info.email.toLowerCase(); // TODO remove, is a quick fix
    if(info.accessToken) {
      this.accessToken = info.accessToken;
    }
    if(info.refreshToken) {
      this.refreshToken = info.refreshToken;
    }
    if(info.orcid) {
      this.orcid = info.orcid;
    }
    this.fullname = (info.name) ? info.name : "";
    if (this.fullname == "") {
      if (this.firstname != "") {
        this.fullname += this.firstname;
      }
      if (this.lastname != "") {
        this.fullname += this.lastname;
      }
      if (this.fullname == "") { //fullname is still empty set a default
        this.fullname = "Anonymous user";
      }
    }
    this.role = [];
    if (info.roles) {
      info.roles.forEach(role => {
        this.role.push(decodeURIComponent(role).replace('$$', '::'));
      });
    } else {
      if (info.edu_person_entitlements) {
        this.role = info.edu_person_entitlements;
      }
    }
    this.expirationDate = info.exp_date;
  }
}

export class Session {
  public static removeUser() {
    COOKIE.deleteCookie(COOKIE.cookieName_id);
  }
  
  /**
   * @deprecated
   *
   * Use userInfoSubject @UserManagementService in order to check if user is logged in
   *
   * */
  public static isLoggedIn(): boolean {
    var cookie = COOKIE.getCookie(COOKIE.cookieName_id);
    return (cookie != null && cookie != "");
  }
  public static clearReloadUrl() {
    COOKIE.setCookie("reloadURLs", JSON.stringify([]), -1);
  }
  public static setReloadUrl(host: string, path: string, params: string, fragment: string) {
    let URLs:any[] = this.getReloadUrl();
    let URL = {};
    URL["host"] = host;
    URL["path"] = path;
    URL["params"] = params;
    URL["fragment"] = fragment;
    URLs.push(URL);
    COOKIE.setCookie("reloadURLs", JSON.stringify(URLs), -1);
  }
  
  public static getReloadUrl() {
    let URLs = COOKIE.getCookie("reloadURLs");
    let array = JSON.parse(URLs);
    return array?array:[];
    
  }
  public static popReloadUrl() {
    let array = this.getReloadUrl();
    let Url = array.length>0?array[0]:null;
    COOKIE.setCookie("reloadURLs", JSON.stringify(array.slice(1)), -1);
    return Url;

  }
  
  public static getParamsObj(params: string) {
    var object = null;
    if (params.split("&").length > 0) {
      object = {};
    }
    params = (params && params.split("?").length > 1) ? params.split("?")[1] : params;
    for (var i = 0; i < params.split("&").length; i++) {
      object[(params.split("&")[i]).split("=")[0]] = decodeURIComponent((params.split("&")[i]).split("=")[1]);
    }
    
    return object;
    
  }
  
  //Methods to check roles
  public static isClaimsCurator(user: User): boolean {
    return user && user.role.indexOf(Role.CURATOR_CLAIM) !== -1;
  }
  
  public static isMonitorCurator(user: User): boolean {
    return StakeholderConfiguration.TYPES.filter(stakeholderType => this.isTypeCurator(stakeholderType.value, user)).length > 0;
  }
  
  public static isCommunityCurator(user: User): boolean {
    return this.isTypeCurator("community", user);
  }
  
  private static isTypeCurator(type: string, user: User): boolean {
    return user && user.role.indexOf(Role.curator(type)) !== -1;
  }
  
  public static isCurator(type: string, user: User): boolean {
    return (type === 'community' || StakeholderConfiguration.TYPES.find(stakeholderType => stakeholderType.value == type)) && this.isTypeCurator(type, user);
  }
  
  public static isPortalAdministrator(user: User): boolean {
    return user && user.role.indexOf(Role.PORTAL_ADMIN) !== -1;
  }
  
  public static isUserManager(user: User): boolean {
    return user && user.role.indexOf(Role.USER_MANAGER) !== -1;
  }
  
  public static isSubscribedTo(type: string, id: string, user: User): boolean {
    return user && user.role.indexOf(Role.member(type, id)) !== -1;
  }
  
  public static isMember(type: string, id: string, user: User): boolean {
    return user && user.role.indexOf(Role.member(type, id)) !== -1;
  }
  
  public static isManager(type: string, id: string, user: User): boolean {
    return user && user.role.indexOf(Role.manager(type, id)) !== -1
  }
  
  public static isKindOfMonitorManager(user: User): boolean {
    if (user) {
      for (let role of user.role) {
        if (role.indexOf('_MANAGER') !== -1) {
          return true;
        }
      }
    }
    return false;
  }
  
  public static isKindOfCommunityManager(user: User): boolean {
    if (user) {
      for (let role of user.role) {
        if (role.indexOf('COMMUNITY') !== -1 && role.indexOf('_MANAGER') !== -1) {
          return true;
        }
      }
    }
    return false;
  }
  
  public static isRegisteredUser(user: User): boolean {
    return user && user.role.indexOf(Role.REGISTERED_USER) !== -1;
  }
}

export class COOKIE {
  public static cookieName_id: string = "AccessToken";
  
  public static getCookie(name: string): string {
    if (typeof document == 'undefined') {
      return null;
    }
    let ca: Array<string> = document.cookie.split(';');
    let caLen: number = ca.length;
    let cookieName = `${name}=`;
    let c: string;
    
    for (let i: number = 0; i < caLen; i += 1) {
      c = ca[i].replace(/^\s+/g, '');
      if (c.indexOf(cookieName) == 0) {
        return c.substring(cookieName.length, c.length);
      }
    }
    return null;
  }
  
  public static deleteCookie(name) {
    this.setCookie(name, '', -1);
  }
  
  public static setCookie(name: string, value: string, expireDays: number, path: string = '/') {
    //TODO fix domain?
    let d: Date = new Date();
    d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000);
    let expires: string = `expires=${d.toUTCString()}`;
    // let cpath:string = path ? `; path=${path}` : '';
    let domain = "";
    if (typeof document !== 'undefined') {
      if (document.domain.indexOf(".di.uoa.gr") != -1) { // for development
        domain = ".di.uoa.gr";
      } else if (document.domain.indexOf(".openaire.eu") != -1) {
        domain = ".openaire.eu";
      }
      document.cookie = name + '=' + value + '; path=' + path + '; domain=' + domain + ';SameSite=Lax;';
    }
  }
}

export class Role {
  public static GROUP = '';
  public static PORTAL_ADMIN = 'PORTAL_ADMINISTRATOR';
  public static REGISTERED_USER = 'REGISTERED_USER';
  public static ANONYMOUS_USER = 'ROLE_ANONYMOUS';
  public static USER_MANAGER = 'USER_MANAGER';
  public static CURATOR_CLAIM = 'CURATOR_CLAIM';

  public static roleName(type: string, id: string) {
    return this.GROUP + this.mapType(type) + '.' + id;
  }

  public static mapType(type: string, communityMap: boolean = true): string {
    type = type.replace(this.GROUP, '');
    if (type == "ri" && communityMap) {
      type = "community";
    } else if (type == "organization") {
      type = "institution";
    }
    return type;
  }
  
  /**
   * Type = FUNDER | COMMUNITY | INSTITUTION | PROJECT
   *
   * */
  public static curator(type: string): string {
    return "CURATOR_" + this.mapType(type, true).toUpperCase();
  }
  
  /**
   * Type = FUNDER | COMMUNITY | INSTITUTION | PROJECT
   *
   * */
  public static typeManager(type: string): string {
    return "MANAGER_" + this.mapType(type, true).toUpperCase();
  }
  
  /**
   * Type = FUNDER | COMMUNITY | INSTITUTION | PROJECT
   *
   * */
  public static typeMember(type: string): string {
    return this.mapType(type, false).toUpperCase();
  }
  
  /**
   * Type = FUNDER | COMMUNITY | INSTITUTION | PROJECT
   *
   * Id = EE, EGI, etc
   * */
  public static manager(type: string, id: string) {
    return this.mapType(type, true).toUpperCase() + "_" + id.toUpperCase() + "_MANAGER";
  }
  
  /**
   * Type = FUNDER | COMMUNITY | RI | INSTITUTION | PROJECT
   *
   * Id = EE, EGI, etc
   * */
  public static member(type: string, id: string) {
    return this.mapType(type, false).toUpperCase() + "_" + id.toUpperCase();
  }
}
