/*
 * Copyright (C) 2022 Savoir-faire Linux Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <https://www.gnu.org/licenses/>.
 */

/* eslint-disable no-undef */
// TODO: This hides eslint errors for this file. This should be removed once this file is cleaned up.

import { PromiseExecutor } from 'jami-web-common';

interface AuthManagerState {
  initialized: boolean;
  authenticated: boolean;
  setupComplete: boolean;
  error: boolean;
}

interface AuthManagerTask extends PromiseExecutor<Response> {
  url: string;
  init?: RequestInit;
}

interface InitData {
  loggedin?: true;
  username?: string;
  type?: string;
  setupComplete?: boolean;
}

type OnAuthChanged = (auth: AuthManagerState) => void;

class AuthManager {
  private authenticating: boolean;
  private readonly _state: AuthManagerState;
  private tasks: AuthManagerTask[];
  private onAuthChanged: OnAuthChanged | undefined;

  constructor() {
    console.log('AuthManager()');
    this.authenticating = false;

    this._state = {
      initialized: false,
      authenticated: true,
      setupComplete: true,
      error: false,
    };

    this.tasks = [];
    this.onAuthChanged = undefined;

    // @ts-ignore
    if (initData) {
      console.log('Using static initData');
      // @ts-ignore
      this.setInitData(initData);
      return;
    }
  }

  isAuthenticated() {
    return this._state.authenticated;
  }

  getState() {
    return this._state;
  }

  setInitData(data: InitData) {
    this.authenticating = false;
    this._state.initialized = true;
    if (data.username) {
      Object.assign(this._state, {
        authenticated: true,
        setupComplete: true,
        error: false,
        user: { username: data.username, type: data.type },
      });
    } else {
      Object.assign(this._state, {
        authenticated: false,
        setupComplete: data.setupComplete ?? true,
        error: false,
      });
    }
    console.log('Init ended');
    /*if (this.onAuthChanged)
            this.onAuthChanged(this._state)*/
  }

  init(cb: OnAuthChanged) {
    this.onAuthChanged = cb;
    if (this._state.initialized || this.authenticating) return;
    /*if (initData) {
            console.log("Using static initData")
            this.setInitData(initData)
            return
        }*/
    this.authenticating = true;
    fetch('/auth')
      .then(async (response) => {
        this.authenticating = false;
        this._state.initialized = true;
        if (response.status === 200) {
          this.setInitData(await response.json());
        } else if (response.status === 401) {
          this.setInitData(await response.json());
        } else {
          this._state.error = true;
          if (this.onAuthChanged) this.onAuthChanged(this._state);
        }
      })
      .catch((e) => {
        this.authenticating = false;
        console.log(e);
      });
  }

  deinit() {
    console.log('Deinit');
    this.onAuthChanged = undefined;
  }

  async setup(password: string) {
    if (this.authenticating || this._state.setupComplete) return;
    console.log('Starting setup');
    this.authenticating = true;
    const response = await fetch(`/setup`, {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ password }),
    });
    console.log(response);
    if (response.ok) {
      console.log('Success, going home');
      //navigate('/')
    }

    this.authenticating = false;
    this._state.setupComplete = true;
    if (this.onAuthChanged) this.onAuthChanged(this._state);
    return response.ok;
  }

  authenticate(username: string, password: string) {
    if (this.authenticating) return;
    console.log('Starting authentication');
    this.authenticating = true;
    fetch(`/auth/local?username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`, {
      method: 'POST',
    })
      .then((response) => {
        console.log(response);
        this.authenticating = false;
        this._state.authenticated = response.ok && response.status === 200;
        if (this.onAuthChanged) this.onAuthChanged(this._state);
        while (true) {
          const task = this.tasks.shift();
          if (!task) {
            break;
          }
          if (this._state.authenticated) {
            fetch(task.url, task.init)
              .then((res) => task.resolve(res))
              .catch((e) => console.log('Error executing pending task: ' + e));
          } else {
            task.reject(new Error('Authentication failed'));
          }
        }
      })
      .catch((e) => {
        this.authenticating = false;
        console.log(e);
      });
  }

  disconnect() {
    console.log('Disconnect');
    this._state.authenticated = false;
    if (this.onAuthChanged) this.onAuthChanged(this._state);
  }

  fetch(url: string, init?: RequestInit): Promise<Response> {
    console.log(`fetch ${url}`);
    if (!this._state.authenticated) {
      if (!init || !init.method || init.method === 'GET') {
        return new Promise<Response>((resolve, reject) => this.tasks.push({ url, init, resolve, reject }));
      } else {
        return new Promise<Response>((resolve, reject) => reject('Not authenticated'));
      }
    }
    return fetch(url, init).then((response) => {
      if (response.status === 401) {
        this.disconnect();
        return this.fetch(url, init);
      }
      return response;
    });
  }
}

export default new AuthManager();
