<?php

declare(strict_types=1);

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Enum\ContractType;
use App\Enum\TrackingMode;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
use Symfony\Component\Serializer\Attribute\Groups;

#[ApiResource(
    normalizationContext: ['groups' => ['contract:read']],
    denormalizationContext: ['groups' => ['contract:write']],
    paginationEnabled: false,
    security: "is_granted('ROLE_ADMIN')"
)]
#[ORM\Entity]
#[ORM\Table(name: 'contracts')]
class Contract
{
    public const string TRACKING_TIME     = TrackingMode::TIME->value;
    public const string TRACKING_PRESENCE = TrackingMode::PRESENCE->value;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    #[Groups(['contract:read', 'employee:read'])]
    private ?int $id = null;

    #[ORM\Column(type: 'string', length: 120)]
    #[Groups(['contract:read', 'contract:write', 'employee:read'])]
    private string $name = '';

    #[ORM\Column(type: 'string', length: 20)]
    #[Groups(['contract:read', 'contract:write', 'employee:read'])]
    private string $trackingMode = self::TRACKING_TIME;

    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['contract:read', 'contract:write', 'employee:read'])]
    private ?int $weeklyHours = null;

    #[ORM\Column(type: 'boolean', options: ['default' => true])]
    #[Groups(['contract:read', 'contract:write'])]
    private bool $isActive = true;

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

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

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

        return $this;
    }

    public function getTrackingMode(): string
    {
        return $this->trackingMode;
    }

    public function getTrackingModeEnum(): TrackingMode
    {
        return TrackingMode::tryFrom($this->trackingMode) ?? TrackingMode::TIME;
    }

    public function setTrackingMode(string|TrackingMode $trackingMode): self
    {
        $value = $trackingMode instanceof TrackingMode ? $trackingMode->value : $trackingMode;
        if (null === TrackingMode::tryFrom($value)) {
            throw new InvalidArgumentException(sprintf('Invalid tracking mode "%s".', $value));
        }

        $this->trackingMode = $value;

        return $this;
    }

    #[Groups(['contract:read', 'employee:read'])]
    public function getType(): ContractType
    {
        return ContractType::resolve($this->name, $this->trackingMode, $this->weeklyHours);
    }

    public function getWeeklyHours(): ?int
    {
        return $this->weeklyHours;
    }

    public function setWeeklyHours(?int $weeklyHours): self
    {
        $this->weeklyHours = $weeklyHours;

        return $this;
    }

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

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

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }
}
