/* eslint-disable no-continue */
import ARIClient from 'ari-client';
import AMIClient from 'asterisk-manager';
import GoogleTTS, { TextToSpeechClient } from '@google-cloud/text-to-speech';
import { Client, Collection, Handler } from '.';

export default class PBX {
  public client: Client;

  public handlers: Collection<Handler>;

  public ari: ARIClient.Client;

  public ami: any;

  public tts: TextToSpeechClient;

  constructor(client: Client) {
    this.client = client;

    this.handlers = new Collection<Handler>();

    this.load();
  }

  private async load() {
    this.ari = await ARIClient.connect('http://10.8.0.1:8088/ari', 'cr0', this.client.config.ariClientKey);
    this.ari.start(['cr-zero', 'page-dtmf']);

    this.ami = new AMIClient(5038, '10.8.0.1', 'cr', this.client.config.amiClientKey);

    process.env.GOOGLE_APPLICATION_CREDENTIALS = `${__dirname}/../../google.json`;
    this.tts = new GoogleTTS.TextToSpeechClient();
    this.start();
  }

  public start() {
    const handlers = Object.values<typeof Handler>(require(`${__dirname}/../pbx`));
    for (const HandlerFile of handlers) {
      const handler = new HandlerFile(this);
      if (!handler.app) continue;
      if (!handler.options?.available) {
        this.ari.on('StasisStart', async (event, channel) => {
          if (event.application !== handler.app) return;
          await handler.unavailable(event, channel);
        });
      } else {
        this.ari.on('StasisStart', async (event, channel) => {
          if (event.application !== handler.app) return;
          try {
            await handler.run(event, channel);
          } catch (err) {
            this.client.util.handleError(err);
          }
        });
      }
      this.handlers.add(handler.app, handler);
      this.client.util.signale.success(`Successfully loaded PBX Handler ${handler.app}`);
    }
  }
}
