package LasTres::Controller::Websocket;

use v5.36.0;

use strict;
use warnings;

use JSON          qw/encode_json/;
use UUID::URandom qw/create_uuid_string/;

use Mojo::Base 'Mojolicious::Controller', -signatures;
use Data::Dumper;

use LasTres::Redis;
use LasTres::Controller::Websocket::InputPackets;

our %SESSIONS;
use LasTres::DAO::PJs;
my $result_set_pjs = LasTres::DAO::PJs->ResultSet;

my $redis         = LasTres::Redis->new;
my $input_packets = LasTres::Controller::Websocket::InputPackets->new;

sub ws ($self) {
    $self->inactivity_timeout(300);
    my $user = $self->user;
    if ( !defined $user ) {
        return $self->render(
            status => 401,
            json   => {
                error => 'You are not logged in.',
            }
        );
    }
    my $session_uuid = create_uuid_string;
    $SESSIONS{$session_uuid} = {
        user       => $user,
        controller => $self,
        uuid       => $session_uuid,
    };
    my $session = $SESSIONS{$session_uuid};
    $self->on(
        json => sub ( $self, $hash ) {
            $self->_handle_packet( $session, $hash );
        }
    );
    $self->on(
        finish => sub ( $self, $code, $reason ) {
            if (defined $session->{redis} && defined $session->{pj}) {
                my $redis = $session->{redis};
                my $pj = $session->{pj};
                $redis->pubsub->unlisten($redis->pj_subscription($pj));
            }
            delete $SESSIONS{$session_uuid};
            $reason ||= "No reason";
            say STDERR
"Websocket for user @{[$user->username]} closed with status $code and reason $reason.";
        }
    );
}

{

    sub _handle_packet ( $self, $session, $hash ) {
        my $command = $hash->{command};
        if ( !defined $command ) {
            say STDERR "No command.";
            $self->send( encode_json( { error => "No command" } ) );
            return;
        }
        my $input_packet = $input_packets->hash->{$command};

        if ( !defined $input_packet ) {
            say STDERR "Unknown command $command.";
            $self->send(
                encode_json( { error => "Unknown command $command" } ) );
            return;
        }
        my $data = $hash->{data};
        return $input_packet->handle( $self, $session, $data );
    }
}
1;
