<?php

namespace App\Resource\Entity;

use App\Resource\Repository\ResourceSkillRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * «این منبع این مهارت را در این سطح دارد.»
 *
 * فرزند aggregate با ریشهٔ {@see ClinicResource} — برخلاف پروندهٔ تسک ۰۱، اینجا ریشه
 * خودش جفت محیط دارد، پس ارث‌بری واقعی است. uuid هم ندارد: تنها راه رسیدن به آن
 * `PUT /api/v1/resource/{uuid}/skills` است.
 */
#[ORM\Entity(repositoryClass: ResourceSkillRepository::class)]
#[ORM\Table(name: 'resource_skills')]
#[ORM\UniqueConstraint(name: 'uniq_resource_skill', columns: ['resource_id', 'skill_id'])]
#[ORM\Index(columns: ['skill_id', 'level'], name: 'idx_resource_skills_skill')]
class ResourceSkill
{
    public const MIN_LEVEL = 1;
    public const MAX_LEVEL = 5;

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

    #[ORM\ManyToOne(targetEntity: ClinicResource::class, inversedBy: 'skills')]
    #[ORM\JoinColumn(name: 'resource_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
    private ClinicResource $resource;

    #[ORM\ManyToOne(targetEntity: Skill::class)]
    #[ORM\JoinColumn(name: 'skill_id', referencedColumnName: 'id', nullable: false, onDelete: 'RESTRICT')]
    private Skill $skill;

    /**
     * ۱..۵. از روز اول هست چون تسک ۰۶ استراتژی «حفظ متخصص‌ها» را روی همین می‌سازد و
     * افزودنش بعداً یعنی backfill با حدس.
     */
    #[ORM\Column(type: 'smallint', options: ['default' => 1])]
    private int $level = 1;

    #[ORM\Column(name: 'created_at', type: 'integer')]
    private int $createdAt;

    public function __construct(ClinicResource $resource, Skill $skill, int $level = 1)
    {
        if ($level < self::MIN_LEVEL || $level > self::MAX_LEVEL) {
            throw new \InvalidArgumentException('Skill level must be between 1 and 5.');
        }

        $this->resource  = $resource;
        $this->skill     = $skill;
        $this->level     = $level;
        $this->createdAt = time();
    }

    public function getId(): ?int                 { return $this->id; }
    public function getResource(): ClinicResource  { return $this->resource; }
    public function getSkill(): Skill              { return $this->skill; }
    public function getLevel(): int                { return $this->level; }
    public function getCreatedAt(): int            { return $this->createdAt; }

    public function toArray(): array
    {
        return [
            'skill_uuid' => $this->skill->getUuid(),
            'skill_name' => $this->skill->getName(),
            'level'      => $this->level,
        ];
    }
}
