package CF::Controller::Websockets;

use Mojo::Base 'Mojolicious::Controller';
use Mojo::Pg::PubSub;
use JSON;
use feature 'signatures';
no warnings qw{ experimental::signatures };

use constant SOCKET_INACTIVITY_TIMEOUT => 300;
use constant USER_ALIVE_TIMEOUT        => 100;

sub main {
    my $c = shift;

    $c->inactivity_timeout(SOCKET_INACTIVITY_TIMEOUT);

    my $user;

    if ( my $key = $c->req->headers->authorization ) {
       if ( $key =~ s/Bearer\s+//i ) {
            $c->oauth_token($key);

            if ( $c->user ) {
                $user = $c->schema->resultset('User')->find_or_create(
                    $c->user, { key => 'uuid'}
                );
            }
        }
    }


    my $pubsub = Mojo::Pg::PubSub->new(pg => $c->pg);

    $pubsub->listen(notify => sub($pubsub, $payload) {
        $c->send($payload);
    });

    $c->on(message => sub( $c, $message ) {
        $user->update({keepalive => \'now()'}) if $user;

        my $min_alive_time = "now() - '" . USER_ALIVE_TIMEOUT. " s'::interval";

        my $alive = $c->schema->resultset('User')->count(
            {
                keepalive => { '>' => \$min_alive_time },
            }
        );
        $c->send(to_json({ online_users => $alive }));

    });

    $c->on(finish => sub ($c, $code, $reason = undef) {
        $pubsub->unlisten('notify');
        $c->app->log->debug("WebSocket closed with status $code");
    });
}

1;