/* eslint-disable no-dupe-class-members */

import Configuration, { ConfigurationOptions } from "./Configuration";
import ApiCall from "./ApiCall";
import Collections from "./Collections";
import Collection from "./Collection";
import Aliases from "./Aliases";
import Alias from "./Alias";
import Keys from "./Keys";
import Key from "./Key";
import Debug from "./Debug";
import Metrics from "./Metrics";
import Stats from "./Stats";
import Health from "./Health";
import Operations from "./Operations";
import MultiSearch from "./MultiSearch";
import Presets from "./Presets";
import Preset from "./Preset";
import AnalyticsV1 from "./AnalyticsV1";
import Analytics from "./Analytics";
import Stopwords from "./Stopwords";
import Stopword from "./Stopword";
import Conversations from "./Conversations";
import Conversation from "./Conversation";
import Stemming from "./Stemming";
import NLSearchModels from "./NLSearchModels";
import NLSearchModel from "./NLSearchModel";
import SynonymSets from "./SynonymSets";
import SynonymSet from "./SynonymSet";
import CurationSets from "./CurationSets";
import CurationSet from "./CurationSet";
export default class Client {
  configuration: Configuration;
  apiCall: ApiCall;
  debug: Debug;
  metrics: Metrics;
  stats: Stats;
  health: Health;
  operations: Operations;
  multiSearch: MultiSearch;
  analytics: Analytics;
  analyticsV1: AnalyticsV1;
  stemming: Stemming;
  private readonly _collections: Collections;
  private readonly individualCollections: Record<string, Collection>;
  private readonly _aliases: Aliases;
  private readonly individualAliases: Record<string, Alias>;
  private readonly _keys: Keys;
  private readonly individualKeys: Record<number, Key>;
  private readonly _presets: Presets;
  private readonly individualPresets: Record<string, Preset>;
  private readonly _stopwords: Stopwords;
  private readonly individualStopwords: Record<string, Stopword>;
  private readonly _conversations: Conversations;
  private readonly individualConversations: Record<string, Conversation>;
  private readonly _nlSearchModels: NLSearchModels;
  private readonly individualNLSearchModels: Record<string, NLSearchModel>;
  private readonly _synonymSets: SynonymSets;
  private readonly individualSynonymSets: Record<string, SynonymSet>;
  private readonly _curationSets: CurationSets;
  private readonly individualCurationSets: Record<string, CurationSet>;

  constructor(options: ConfigurationOptions) {
    options.sendApiKeyAsQueryParam = options.sendApiKeyAsQueryParam ?? false;

    this.configuration = new Configuration(options);
    this.apiCall = new ApiCall(this.configuration);
    this.debug = new Debug(this.apiCall);
    this.metrics = new Metrics(this.apiCall);
    this.stats = new Stats(this.apiCall);
    this.health = new Health(this.apiCall);
    this.operations = new Operations(this.apiCall);
    this.multiSearch = new MultiSearch(this.apiCall, this.configuration);
    this._collections = new Collections(this.apiCall);
    this.individualCollections = {};
    this._aliases = new Aliases(this.apiCall);
    this.individualAliases = {};
    this._keys = new Keys(this.apiCall);
    this.individualKeys = {};
    this._presets = new Presets(this.apiCall);
    this.individualPresets = {};
    this._stopwords = new Stopwords(this.apiCall);
    this.individualStopwords = {};
    this.analytics = new Analytics(this.apiCall);
    this.analyticsV1 = new AnalyticsV1(this.apiCall);
    this.stemming = new Stemming(this.apiCall);
    this._conversations = new Conversations(this.apiCall);
    this.individualConversations = {};
    this._nlSearchModels = new NLSearchModels(this.apiCall);
    this.individualNLSearchModels = {};
    this._synonymSets = new SynonymSets(this.apiCall);
    this.individualSynonymSets = {};
    this._curationSets = new CurationSets(this.apiCall);
    this.individualCurationSets = {};
  }

  collections(): Collections;
  collections<T extends Record<string, any> = object>(
    collectionName: string,
  ): Collection<T>;
  collections(collectionName?: string): Collections | Collection {
    if (collectionName === undefined) {
      return this._collections;
    } else {
      if (this.individualCollections[collectionName] === undefined) {
        this.individualCollections[collectionName] = new Collection(
          collectionName,
          this.apiCall,
          this.configuration,
        );
      }
      return this.individualCollections[collectionName];
    }
  }

  aliases(): Aliases;
  aliases(aliasName: string): Alias;
  aliases(aliasName?: string): Aliases | Alias {
    if (aliasName === undefined) {
      return this._aliases;
    } else {
      if (this.individualAliases[aliasName] === undefined) {
        this.individualAliases[aliasName] = new Alias(aliasName, this.apiCall);
      }
      return this.individualAliases[aliasName];
    }
  }

  keys(): Keys;
  keys(id: number): Key;
  keys(id?: number): Keys | Key {
    if (id === undefined) {
      return this._keys;
    } else {
      if (this.individualKeys[id] === undefined) {
        this.individualKeys[id] = new Key(id, this.apiCall);
      }
      return this.individualKeys[id];
    }
  }

  presets(): Presets;
  presets(id: string): Preset;
  presets(id?: string): Presets | Preset {
    if (id === undefined) {
      return this._presets;
    } else {
      if (this.individualPresets[id] === undefined) {
        this.individualPresets[id] = new Preset(id, this.apiCall);
      }
      return this.individualPresets[id];
    }
  }

  stopwords(): Stopwords;
  stopwords(id: string): Stopword;
  stopwords(id?: string): Stopwords | Stopword {
    if (id === undefined) {
      return this._stopwords;
    } else {
      if (this.individualStopwords[id] === undefined) {
        this.individualStopwords[id] = new Stopword(id, this.apiCall);
      }
      return this.individualStopwords[id];
    }
  }

  conversations(): Conversations;
  conversations(id: string): Conversation;
  conversations(id?: string): Conversations | Conversation {
    if (id === undefined) {
      return this._conversations;
    } else {
      if (this.individualConversations[id] === undefined) {
        this.individualConversations[id] = new Conversation(id, this.apiCall);
      }
      return this.individualConversations[id];
    }
  }

  nlSearchModels(): NLSearchModels;
  nlSearchModels(id: string): NLSearchModel;
  nlSearchModels(id?: string): NLSearchModels | NLSearchModel {
    if (id === undefined) {
      return this._nlSearchModels;
    } else {
      if (this.individualNLSearchModels[id] === undefined) {
        this.individualNLSearchModels[id] = new NLSearchModel(id, this.apiCall);
      }
      return this.individualNLSearchModels[id];
    }
  }

  synonymSets(): SynonymSets;
  synonymSets(synonymSetName: string): SynonymSet;
  synonymSets(synonymSetName?: string): SynonymSets | SynonymSet {
    if (synonymSetName === undefined) {
      return this._synonymSets;
    } else {
      if (this.individualSynonymSets[synonymSetName] === undefined) {
        this.individualSynonymSets[synonymSetName] = new SynonymSet(
          synonymSetName,
          this.apiCall,
        );
      }
      return this.individualSynonymSets[synonymSetName];
    }
  }

  curationSets(): CurationSets;
  curationSets(name: string): CurationSet;
  curationSets(name?: string): CurationSets | CurationSet {
    if (name === undefined) {
      return this._curationSets;
    } else {
      if (this.individualCurationSets[name] === undefined) {
        this.individualCurationSets[name] = new CurationSet(
          name,
          this.apiCall,
        );
      }
      return this.individualCurationSets[name];
    }
  }
}
