<?php

declare(strict_types=1);

namespace App\Entity;

use App\Repository\DartThrowRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: DartThrowRepository::class)]
#[ORM\Table(name: 'dart_throw')]
#[ORM\Index(name: 'idx_throw_game_created_at', columns: ['game_id', 'created_at'])]
#[ORM\UniqueConstraint(name: 'uniq_throw_dart_index_per_turn', columns: ['turn_id', 'dart_index'])]
class DartThrow
{
    #[ORM\Id]
    #[ORM\Column(type: Types::GUID, unique: true)]
    private string $id;

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

    #[ORM\ManyToOne(inversedBy: 'throws')]
    #[ORM\JoinColumn(nullable: false)]
    private Turn $turn;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(nullable: false)]
    private GamePlayer $player;

    #[ORM\Column]
    private int $dartIndex;

    #[ORM\Column(nullable: true)]
    private ?int $segment = null;

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

    #[ORM\Column(nullable: true)]
    private ?int $multiplier = null;

    #[ORM\Column(nullable: true)]
    private ?int $bullValue = null;

    #[ORM\Column]
    private int $scoredPoints;

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

    public function __construct(
        Game $game,
        Turn $turn,
        GamePlayer $player,
        int $dartIndex,
        int $scoredPoints,
        bool $isBull,
        ?int $segment,
        ?int $multiplier,
        ?int $bullValue,
        ?\DateTimeImmutable $createdAt = null,
    ) {
        $this->id = Uuid::v7()->toRfc4122();
        $this->game = $game;
        $this->turn = $turn;
        $this->player = $player;
        $this->dartIndex = $dartIndex;
        $this->scoredPoints = $scoredPoints;
        $this->isBull = $isBull;
        $this->segment = $segment;
        $this->multiplier = $multiplier;
        $this->bullValue = $bullValue;
        $this->createdAt = $createdAt ?? 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 getTurn(): Turn
    {
        return $this->turn;
    }

    public function setTurn(Turn $turn): self
    {
        $this->turn = $turn;

        return $this;
    }

    public function getPlayer(): GamePlayer
    {
        return $this->player;
    }

    public function setPlayer(GamePlayer $player): self
    {
        $this->player = $player;

        return $this;
    }

    public function getDartIndex(): int
    {
        return $this->dartIndex;
    }

    public function getSegment(): ?int
    {
        return $this->segment;
    }

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

    public function isOut(): bool
    {
        return !$this->isBull
            && $this->segment === null
            && $this->multiplier === null
            && $this->bullValue === null
            && $this->scoredPoints === 0;
    }

    public function getMultiplier(): ?int
    {
        return $this->multiplier;
    }

    public function getBullValue(): ?int
    {
        return $this->bullValue;
    }

    public function getScoredPoints(): int
    {
        return $this->scoredPoints;
    }

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