use strict;
use warnings;

use experimental 'signatures';
use Nei::Mojo::Reactor::Irssi4;
use Irssi ();

use Mojo::UserAgent;
use Mojo::Promise;

my @gtx;
my $ua = Mojo::UserAgent->new;

sub ws_received_message ($tx, $msg) {
    Irssi::print("WebSocket message: $msg");
}

sub ws_finished ($tx, $code, @info) {
    Irssi::print("WebSocket closed with status $code.");
    @gtx = grep { $_ != $tx } @gtx;
}

sub ws_connected ($ua, $tx) {
    unless ($tx->is_websocket) {
	Irssi::print('WebSocket handshake failed!');
	if (my $err = $tx->error) {
	    if ($err->{code}) {
		Irssi::print("$err->{code} response: $err->{message}");
	    } else {
		Irssi::print("Connection error: $err->{message}");
	    }
	}
	return;
    }
    Irssi::print("WebSocket connected");
    push @gtx, $tx;
    $tx->on(finish => \&ws_finished);
    $tx->on(message => \&ws_received_message);
}

sub cmd_ws_connect ($data, $server, $witem) {
    my $ws_addr = "ws://127.0.0.1:3000/";
    $ua->websocket($ws_addr => \&ws_connected);
}

sub cmd_ws_send ($data, $server, $witem) {
    if (@gtx) {
	Irssi::print("Sending $data to WebSocket");
	$gtx[-1]->send($data);
    } else {
	Irssi::print("No WebSocket connection, try /ws_connect");
    }
}

sub cmd_ws_close ($data, $server, $witem) {
    if (@gtx) {
	Irssi::print("Closing WebSocket");
	$gtx[-1]->finish;
    } else {
	Irssi::print("No WebSocket connections open");
    }
}

sub cmd_ws_connections ($data, $server, $witem) {
    Irssi::print("I have @{[ scalar @gtx ]} open connections");
}

Irssi::command_bind('ws_connect' => 'cmd_ws_connect');
Irssi::command_bind('ws_send' => 'cmd_ws_send');
Irssi::command_bind('ws_close' => 'cmd_ws_close');
Irssi::command_bind('ws_connections' => 'cmd_ws_connections');

sub UNLOAD {
    $ua = undef;
    for my $tx (@gtx) {
	$tx->finish if $tx;
    }
    return undef;
}
