<?php

/** @noinspection PhpUnhandledExceptionInspection */

namespace DefStudio\GameEngine\Models\Concerns;

use DefStudio\GameEngine\Models\Team;
use DefStudio\GameEngine\Exceptions\TeamException;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use DefStudio\GameEngine\Events\Teams\UserSubscribedToTeam;
use DefStudio\GameEngine\Events\Teams\UserUnsubscribedFromTeam;
use function game_engine;

trait HasTeams
{
    /**
     * @return BelongsToMany<Team>
     */
    public function teams(): BelongsToMany
    {
        return $this->belongsToMany(game_engine()->teamClass(), config('game-engine.teams.subscriptions_table'))
            ->withTimestamps();
    }

    /**
     * @return BelongsToMany<Team>
     */
    public function current_teams(): BelongsToMany
    {
        /** @phpstan-ignore-next-line */
        return $this->belongsToMany(game_engine()->teamClass())
            ->where('organization_id', $this->current_organization_id)
            ->withTimestamps();
    }

    public function belongs_to_team(Team $team): bool
    {
        return $this->has_attached($team);
    }

    public function subscribe_to_team(Team $team): self
    {
        $this->ensure_belongs_to_organization($team->organization);

        throw_if($this->belongs_to_team($team), TeamException::already_subscribed());

        $this->teams()->attach($team);

        UserSubscribedToTeam::dispatch($this, $team);

        return $this;
    }

    public function unsubscribe_from_team(Team $team): self
    {
        throw_if(!$this->belongs_to_team($team), TeamException::team_membership_failure());

        $this->teams()->detach($team);

        UserUnsubscribedFromTeam::dispatch($this, $team);

        return $this;
    }
}
