import { string } from "prop-types";

export interface KeyValuePair {
  key: string;
  value: string;
}

export interface FronteggOptions {
  baseUrl: string;
  tokenResolver: () => string;
  additionalQueryParamsResolver?: () => KeyValuePair[];
  additionalHeadersResolver?: () => KeyValuePair[];
}


export default class Config {
  private static instance: Config;
  private options: FronteggOptions;

  public async token(): Promise<string> {
    return await this.options.tokenResolver();
  }

  public get baseUrl(): string {
    let baseUrl = this.options.baseUrl;
    // Append everything we need to the base url
    if (!baseUrl.endsWith('/')) { baseUrl += '/' }
    if (!baseUrl.endsWith('frontegg')) { baseUrl += 'frontegg' }

    return baseUrl
  }

  public async additionalQueryParams(): Promise<KeyValuePair[]> {
    let output = [];
    if (this.options.additionalQueryParamsResolver) {
      output = await this.options.additionalQueryParamsResolver();
    }

    return output;
  }

  public async additionalHeaders(): Promise<KeyValuePair[]> {
    let output = [];
    if (this.options.additionalHeadersResolver) {
      output = await this.options.additionalHeadersResolver();
    }

    return output;
  }

  // Mandatory for singleton pattern
  private constructor() { }

  static getInstance() {
    if (!Config.instance) {
      Config.instance = new Config();
    }
    return Config.instance;
  }

  static init(options: FronteggOptions) {
    const instance = Config.getInstance();

    if (!options) { throw new Error('Invalid options') };
    if (!options.baseUrl) { throw new Error('Base URL is mandatory') };
    if (!options.tokenResolver) { throw new Error('Token resolver is mandatory') };

    instance.options = {
      ...options
    };
  }

}