<?php

/** @noinspection PhpUnused */

namespace DefStudio\GameEngine\Models;

use DefStudio\GameEngine\Enums\Role;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use DefStudio\GameEngine\Models\Concerns\HasStories;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use DefStudio\GameEngine\Database\Factories\TeamFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use DefStudio\GameEngine\Models\Concerns\CanCheckRelationships;

/**
 * @property int $organization_id
 * @property Collection<int, User> $players
 * @property Collection<int, User> $masters
 *
 * @method static TeamFactory factory(array|callable|int|null $count = null, array|callable $state = [])
 */
class Team extends Model
{
    use HasFactory;
    use CanCheckRelationships;
    use HasStories;

    protected $fillable = [
        'name',
        'organization_id',
    ];

    public function getTable()
    {
        return config('game-engine.teams.table', parent::getTable());
    }

    protected static function newFactory(): TeamFactory
    {
        return TeamFactory::new();
    }

    /**
     * @return BelongsToMany<User>
     */
    public function players(): BelongsToMany
    {
        /** @phpstan-ignore-next-line */
        return $this->belongsToMany(\game_engine()->userClass(), 'team_user')
            ->whereHas('organizations', function(Builder $query): void {
                $query
                    ->join('teams', 'teams.id', '=', 'team_user.team_id')
                    ->whereRaw('organization_user.organization_id = teams.organization_id')
                    ->where('role', Role::player);
            })
            ->withTimestamps();
    }

    /**
     * @return BelongsToMany<User>
     */
    public function masters(): BelongsToMany
    {
        /** @phpstan-ignore-next-line */
        return $this->belongsToMany(\game_engine()->userClass(), 'team_user')
            ->whereHas('organizations', function(Builder $query): void {
                $query
                    ->join('teams', 'teams.id', '=', 'team_user.team_id')
                    ->whereRaw('organization_user.organization_id = teams.organization_id')
                    ->where('role', Role::master);
            })
            ->withTimestamps();
    }

    /**
     * @return BelongsTo<Organization, Team>
     */
    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class);
    }
}
