<?php

declare(strict_types=1);

namespace App\Entity;

use App\Repository\GamePlayerRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: GamePlayerRepository::class)]
#[ORM\UniqueConstraint(name: 'uniq_game_player_position', columns: ['game_id', 'position'])]
#[ORM\HasLifecycleCallbacks]
class GamePlayer
{
    #[ORM\Id]
    #[ORM\Column(type: Types::GUID, unique: true)]
    private string $id;

    #[ORM\ManyToOne(inversedBy: 'players')]
    #[ORM\JoinColumn(nullable: false)]
    private Game $game;

    #[ORM\Column(length: 60)]
    #[Assert\NotBlank]
    private string $name;

    #[ORM\Column]
    private int $position;

    #[ORM\Column]
    private int $currentScore;

    #[ORM\Column]
    private bool $isWinner = false;

    #[ORM\Column]
    private bool $hasCheckedIn = true;

    #[ORM\OneToMany(mappedBy: 'player', targetEntity: Turn::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
    private Collection $turns;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private \DateTimeImmutable $createdAt;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private \DateTimeImmutable $updatedAt;

    public function __construct(string $name, int $position, int $startScore)
    {
        $this->id = Uuid::v7()->toRfc4122();
        $this->name = $name;
        $this->position = $position;
        $this->currentScore = $startScore;
        $this->turns = new ArrayCollection();
        $this->createdAt = new \DateTimeImmutable();
        $this->updatedAt = new \DateTimeImmutable();
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function getGame(): Game
    {
        return $this->game;
    }

    public function setGame(Game $game): self
    {
        $this->game = $game;

        return $this;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getPosition(): int
    {
        return $this->position;
    }

    public function setPosition(int $position): self
    {
        $this->position = $position;

        return $this;
    }

    public function getCurrentScore(): int
    {
        return $this->currentScore;
    }

    public function setCurrentScore(int $currentScore): self
    {
        $this->currentScore = $currentScore;

        return $this;
    }

    public function isWinner(): bool
    {
        return $this->isWinner;
    }

    public function setIsWinner(bool $isWinner): self
    {
        $this->isWinner = $isWinner;

        return $this;
    }

    public function hasCheckedIn(): bool
    {
        return $this->hasCheckedIn;
    }

    public function setHasCheckedIn(bool $hasCheckedIn): self
    {
        $this->hasCheckedIn = $hasCheckedIn;

        return $this;
    }

    /** @return Collection<int, Turn> */
    public function getTurns(): Collection
    {
        return $this->turns;
    }

    public function addTurn(Turn $turn): self
    {
        if (!$this->turns->contains($turn)) {
            $this->turns->add($turn);
            $turn->setPlayer($this);
        }

        return $this;
    }

    public function removeTurn(Turn $turn): self
    {
        $this->turns->removeElement($turn);

        return $this;
    }

    public function getCreatedAt(): \DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function getUpdatedAt(): \DateTimeImmutable
    {
        return $this->updatedAt;
    }

    #[ORM\PrePersist]
    public function onPrePersist(): void
    {
        $now = new \DateTimeImmutable();
        $this->createdAt = $now;
        $this->updatedAt = $now;
    }

    #[ORM\PreUpdate]
    public function onPreUpdate(): void
    {
        $this->updatedAt = new \DateTimeImmutable();
    }
}
