package LasTres::Enemy;

use v5.36.0;

use strict;
use warnings;

use feature 'signatures';

use Moo;

use UUID::URandom qw/create_uuid_string/;
use LasTres::Stats;

has uuid => (
    is      => 'rw',
    default => sub ($self) {
        return create_uuid_string();
    },
);

has race => (
    is       => 'rw',
    required => 1,
    accessor => "race_string",
);

has nick => (
    is       => 'rw',
    required => 1,
);

has born_stats => (
    is      => 'rw',
    default => \&_build_born_stats
);

has training_stats => (
    is      => 'rw',
    default => \&_build_training_stats,
);

has level => (
    is       => 'rw',
    required => 1,
);

has team => ( is => 'rw', );

has zhealth => (
    is      => 'rw',
    default => sub ($self) {
        return $self->max_health;
    },
    accessor => "health",
);

has zmana => (
    is      => 'rw',
    default => sub ($self) {
        return $self->max_mana;
    },
    accessor => "mana",
);

has combat_target => (
    is       => 'rw',
    accessor => "_combat_target",
);

after team => sub ( $self, @extra ) {
    if ( ref $self->{team} && !Scalar::Util::isweak( $self->{team} ) ) {
        Scalar::Util::weaken( $self->{team} );
    }
};

sub update_team_sprites ($self) {
}

sub _build_born_stats ($self) {
    return LasTres::Stats->new(
        health       => int( rand(32) ),
        mana         => int( rand(32) ),
        strength     => int( rand(32) ),
        resistance   => int( rand(32) ),
        magic        => int( rand(32) ),
        speed        => int( rand(32) ),
        intelligence => int( rand(32) ),
    );
}

sub _build_training_stats ($self) {

    # We assume that most enemies does not have sense that they trained before.
    return LasTres::Stats->new(
        health       => 0,
        mana         => 0,
        strength     => 0,
        resistance   => 0,
        magic        => 0,
        speed        => 0,
        intelligence => 0,
    );
}

sub experience ($self) {
    return $self->level**3;
}

sub combat_action ($self) {
    return;
}

sub combat_target ( $self, @extra ) {
    my $set;
    if (@extra) {
        $set = shift @extra;
    }
    if ( !defined $self->_combat_target ) {
        $self->team( $self->team->get_from_storage );
        my $battle_uuid         = $self->team->current_battle;
        my $battle              = LasTres::Battle->get_redis($battle_uuid);
        my $target_team         = $battle->get_enemy_team( $self->team );
        my $target_team_members = $target_team->combat_members;
        @$target_team_members = grep { $_->health > 0 } @$target_team_members;
        if ( !@$target_team_members ) {
            return;
        }
        my $target_index =
          LasTres::Util::rand_range_int( 0, $#$target_team_members );
        $self->_combat_target( $target_team_members->[$target_index]->uuid );
    }
    if ( defined $set ) {
        $self->_combat_target($set);
    }
    return $self->_combat_target;
}

sub to_hash_display ($self) {
    my $race = $self->race;
    my $image;
    if ( $race->can('image') ) {
        $image = $race->image;
    }
    return {
        uuid       => $self->uuid,
        nick       => $self->nick,
        race       => $self->race_string,
        health     => $self->health,
        max_health => $self->max_health,
        mana       => $self->mana,
        max_mana   => $self->max_mana,
        level      => $self->level,
        (
              ( defined $image )
            ? ( image => $image )
            : ()
        ),
    };
}

sub gain_experience {
}

sub to_hash ($self) {
    return {
        kind           => 'NPCEnemy',
        uuid           => $self->uuid,
        race           => $self->race_string,
        nick           => $self->nick,
        born_stats     => $self->born_stats->to_hash,
        training_stats => $self->training_stats->to_hash,
        level          => $self->level,
        health         => $self->health,
        mana           => $self->mana,
    };
}

sub from_hash ( $class, $hash ) {
    return $class->new(
        uuid           => $hash->{uuid},
        race           => $hash->{race},
        nick           => $hash->{nick},
        born_stats     => LasTres::Stats->from_hash( $hash->{born_stats} ),
        training_stats => LasTres::Stats->from_hash( $hash->{training_stats} ),
        level          => $hash->{level},
        zhealth        => $hash->{health},
        zmana          => $hash->{mana},
    );
}

sub get_from_storage($self) {
    return $self;
}
with 'LasTres::RedisEnemy';
1;
