/* eslint-disable consistent-return */
import { Message } from 'eris';
import type { Channel } from 'ari-client';
import { Client, Command } from '../class';
import { Misc } from '../pbx';

export default class SIP extends Command {
  constructor(client: Client) {
    super(client);
    this.name = 'sip';
    this.description = 'Dials a SIP URI.';
    this.usage = `${this.client.config.prefix}sip <uri>`;
    this.permissions = 1;
    this.guildOnly = true;
    this.enabled = true;
  }

  public async run(message: Message, args: string[]) {
    try {
      const staff = await this.client.db.Staff.findOne({ userID: message.author.id });
      if (!staff || !staff?.extension) return this.error(message.channel, 'You must have an extension to complete this action.');
      this.success(message.channel, 'Queued call.');

      const bridge = await this.client.pbx.ari.Bridge().create();
      let receiver: Channel = this.client.pbx.ari.Channel();
      let sender: Channel = this.client.pbx.ari.Channel();

      try {
        sender = await this.client.pbx.ari.channels.originate({
          endpoint: `PJSIP/${staff.extension}`,
          extension: staff.extension,
          callerId: 'LOC PBX OPERATOR <operator>',
          context: 'from-internal',
          priority: 1,
          app: 'cr-zero',
        });
      } catch {
        return this.error(message.channel, 'Unable to dial your extension.');
      }

      sender.once('StasisStart', async () => {
        await Misc.play(this.client.pbx, sender, 'sound:pls-hold-while-try');
        await sender.ring();

        try {
          receiver = await receiver.originate({
            endpoint: `SIP/${args.join(' ')}`,
            callerId: 'LOC PBX OPERATOR <operator>',
            context: 'from-internal',
            priority: 1,
            app: 'cr-zero',
          });
        } catch {
          await Misc.play(this.client.pbx, sender, 'sound:discon-or-out-of-service');
          await sender.hangup().catch(() => {});
          return false;
        }

        // receiver.once('StasisStart', )
      });

      receiver.once('StasisStart', async () => {
        await sender.ringStop();
        await bridge.addChannel({ channel: [receiver.id, sender.id] });
        await bridge.play({ media: 'sound:beep' });
      });

      receiver.once('ChannelDestroyed', async () => {
        if (!sender.connected) return;
        await Misc.play(this.client.pbx, sender, ['sound:the-number-u-dialed', 'sound:T-is-not-available', 'sound:please-try-again-later']);
        await sender.hangup().catch(() => {});
        await bridge.destroy().catch(() => {});
      });

      receiver.once('StasisEnd', async () => {
        await sender.hangup().catch(() => {});
        await bridge.destroy().catch(() => {});
      });
      sender.once('StasisEnd', async () => {
        await receiver.hangup().catch(() => {});
        await bridge.destroy().catch(() => {});
      });
    } catch (err) {
      return this.client.util.handleError(err, message, this);
    }
  }
}
