package LasTres::Controller::Websocket::InputPacket::Init;

use v5.36.0;

use strict;
use warnings;

use feature 'signatures';

use Data::Dumper;

use Moo;

use JSON qw/to_json from_json/;

use LasTres::Flags;
use LasTres::DAO::PJs;

with 'LasTres::Controller::Websocket::InputPacket';

my $redis          = LasTres::Redis->new;
my $result_set_pjs = LasTres::DAO::PJs->ResultSet;

sub identifier {
    return 'init';
}

sub handle ( $self, $ws, $session, $data ) {
    if ( ref $data ne 'HASH' ) {
        return $ws->send( to_json( { error => "Data should be a hashref." } ) );
    }
    my $pj_uuid = $data->{pj_uuid};
    if ( !defined $pj_uuid ) {
        return $ws->send( to_json( { error => "No pj sent." } ) );
    }
    my @pjs = $result_set_pjs->search( { uuid => $pj_uuid } );
    if ( !scalar @pjs ) {
        return $ws->send( to_json( { error => 'This pj does not exists' } ) );
    }
    my $pj   = $pjs[0];
    my $user = $session->{user};
    if ( $pj->owner->uuid ne $user->uuid ) {
        return $ws->send(
            to_json( { error => 'You are not the owner of this pj.' } ) );
    }
    $session->{pj} = $pj;
    my $team             = $pj->team;
    my @team_members     = $team->members;
    my @friends          = grep { $pj->uuid ne $_->uuid } @team_members;
    my $team_pjs         = [ map { $_->hash } ( $pj, @friends ) ];
    my $location         = $team->location;
    my $connected_places = $self->_get_connected_places($pj);

    $pj->append_log_line(
        [ { text => 'Nueva conexion a este pj.', color => 'red', background => 'black' }, ] );

    if ( !$pj->get_flag( LasTres::Flags::INTRO_MESSAGE_SENT_FLAG() ) ) {
        $pj->set_flag(LasTres::Flags::INTRO_MESSAGE_SENT_FLAG);
        $pj->append_log_line(
            [
                { text => 'Bienvenido a ' },
                { text => 'LasTres', color => 'green' },
                { text => '. Esperamos que disfrutes del juego.' }
            ]
        );
        $pj->location->show_intro($pj);
    }

    my $info_packet_to_send =
      LasTres::Controller::Websocket::OutputPacket::Info->new(
        set_log       => [ $pj->last_50_log ],
        team_pjs      => $team_pjs,
        location_data => {
            current          => $location->hash,
            connected_places => $connected_places,
        },
        clear => $JSON::true,
      );
    $info_packet_to_send->send($ws);
    my $redis = LasTres::Redis->new;
    $redis->subscribe(
        $redis->pj_subscription($pj),
        my $save = sub ( $message, $topic, $topics ) {
            return $self->_on_redis_event( $ws, $session, $message, $topic,
                $topics );
        }
    );
    $session->{redis} = $redis;
}

sub _on_redis_event ( $self, $ws, $session, $message, $topic, $topics ) {
    my $data = from_json($message);
    $session->{pj} = $session->{pj}->get_from_storage;
    my $pj   = $session->{pj};
    if ( $data->{command} eq 'append-log' ) {
        my $info_packet_to_send =
          LasTres::Controller::Websocket::OutputPacket::Info->new(
            append_log => $data->{log} );
        $info_packet_to_send->send($ws);
        return;
    }
    if ( $data->{command} eq 'update-location' ) {
        my $team = $pj->team;
        my $location = $team->location;
        my $connected_places = $self->_get_connected_places($pj);
        my $info_packet_to_send =
          LasTres::Controller::Websocket::OutputPacket::Info->new(
            location_data => {
                current          => $location->hash,
                connected_places => $connected_places,
            },
          );

        $info_packet_to_send->send($ws);
        return;
    }
}

sub _get_connected_places ( $self, $pj ) {
    my $team     = $pj->team;
    my $location = $team->location;

    my $connected_places = $location->get_available_locations_to_move_to($pj);
    @$connected_places = map { $_->hash } @$connected_places;
    return $connected_places;
}
1;
