import request from "../request";
import sha from "../sha512";
import {
   setCookie,
   getCookie
} from "../cookie"

export interface TwoFactor {
   id: string;
   name: string;
   type: TFATypes;
}

export enum TFATypes {
   OTC,
   BACKUP_CODE,
   U2F,
   APP_ALLOW
}

const Api = {
   // twofactor: [{
   //    id: "1",
   //    name: "Backup Codes",
   //    type: TFATypes.BACKUP_CODE
   // }, {
   //    id: "2",
   //    name: "YubiKey",
   //    type: TFATypes.U2F
   // }, {
   //    id: "3",
   //    name: "Authenticator",
   //    type: TFATypes.OTC
   // }] as TwoFactor[],
   getUsername() {
      return this.username || getCookie("username");
   },
   async setUsername(username: string): Promise<{ error: string | undefined }> {
      return request("/api/user/login", {
         type: "username",
         username
      }, "POST").then(res => {
         this.salt = res.salt;
         this.username = username;
         return {
            error: undefined
         }
      }).catch(err => {
         let error = err.message;
         return { error }
      })
   },
   async setPassword(password: string): Promise<{ error: string | undefined, twofactor?: any }> {
      let pw = sha(this.salt + password);
      return request("/api/user/login", {
         type: "password"
      }, "POST", {
            username: this.username,
            password: pw
         }
      ).then(({
         login,
         special,
         tfa
      }) => {

         this.login = login;
         this.special = special;

         if (tfa && Array.isArray(tfa) && tfa.length > 0)
            this.twofactor = tfa;
         else
            this.twofactor = undefined;


         return {
            error: undefined
         }
      }).catch(err => {
         let error = err.message;
         return { error }
      })
   },
   gettok() {
      return {
         login: this.login.token,
         special: this.special.token
      }
   },
   async sendBackup(id: string, code: string) {
      return request("/api/user/twofactor/backup", this.gettok(), "PUT", { code, id }).then(({ login_exp, special_exp }) => {
         this.login.expires = login_exp;
         this.special.expires = special_exp;
         return {};
      }).catch(err => ({ error: err.message }));
   },
   async sendOTC(id: string, code: string) {
      return request("/api/user/twofactor/otc", this.gettok(), "PUT", { code, id }).then(({ login_exp, special_exp }) => {
         this.login.expires = login_exp;
         this.special.expires = special_exp;
         return {};
      }).catch(error => ({ error: error.message }))
   },
   async finish() {
      let d = new Date()
      d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000)); //Keep the username 30 days
      setCookie("username", this.username, d.toUTCString());

      setCookie("login", this.login.token, new Date(this.login.expires).toUTCString());
      setCookie("special", this.special.token, new Date(this.special.expires).toUTCString());

      let url = new URL(window.location.href);
      let state = url.searchParams.get("state")
      let red = "/"

      if (state) {
         let base64 = url.searchParams.get("base64")
         if (base64)
            red = atob(state)
         else
            red = state
      }
      window.location.href = red;
   }
}

export default Api;