<?php

namespace App\Resource\Entity;

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

/**
 * شیفت تکرارشوندهٔ هفتگی یک منبع — لایهٔ دومِ کسرِ بند ۹ مستند.
 *
 * فرزند aggregate با ریشهٔ {@see ClinicResource} که خودش جفت محیط دارد و uuid این
 * ردیف هرگز از request نمی‌آید (تنها راهش `PUT /resource/{uuid}/calendar` است).
 *
 * عمداً `WeeklySchedule` را بازاستفاده نمی‌کند: آن JSON per جفت (پزشک، کلینیک) است و
 * دست زدن به شکلش یعنی دست زدن به مسیر اسلاتی که در این فاز قفل است
 * ({@see docs/new_feture/taskes/_shared/red-lines.md}). این جدول مسیر موازیِ منبع است.
 */
#[ORM\Entity(repositoryClass: ResourceCalendarRepository::class)]
#[ORM\Table(name: 'resource_calendars')]
#[ORM\UniqueConstraint(name: 'uniq_rc_resource_day_seq', columns: ['resource_id', 'day_of_week', 'sequence'])]
#[ORM\Index(columns: ['resource_id', 'day_of_week', 'active'], name: 'idx_rc_resource_day')]
class ResourceCalendar
{
    public const MINUTES_IN_DAY = 1440;

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

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

    /** ۰=شنبه … ۶=جمعه — همان قرارداد SlotCalculatorService و ساعت کاری شعبه */
    #[ORM\Column(name: 'day_of_week', type: 'smallint')]
    private int $dayOfWeek;

    #[ORM\Column(type: 'smallint', options: ['default' => 0])]
    private int $sequence = 0;

    #[ORM\Column(name: 'start_minute', type: 'smallint')]
    private int $startMinute;

    #[ORM\Column(name: 'end_minute', type: 'smallint')]
    private int $endMinute;

    #[ORM\Column(type: 'boolean', options: ['default' => true])]
    private bool $active = true;

    public function __construct(
        ClinicResource $resource,
        int $dayOfWeek,
        int $startMinute,
        int $endMinute,
        int $sequence = 0,
    ) {
        $this->resource    = $resource;
        $this->dayOfWeek   = $dayOfWeek;
        $this->startMinute = $startMinute;
        $this->endMinute   = $endMinute;
        $this->sequence    = $sequence;
    }

    public function getId(): ?int                 { return $this->id; }
    public function getResource(): ClinicResource { return $this->resource; }
    public function getDayOfWeek(): int           { return $this->dayOfWeek; }
    public function getSequence(): int            { return $this->sequence; }
    public function getStartMinute(): int         { return $this->startMinute; }
    public function getEndMinute(): int           { return $this->endMinute; }
    public function isActive(): bool              { return $this->active; }

    public function setActive(bool $v): self { $this->active = $v; return $this; }

    public function toArray(): array
    {
        return [
            'sequence'     => $this->sequence,
            'start_minute' => $this->startMinute,
            'end_minute'   => $this->endMinute,
            'start_time'   => self::formatMinute($this->startMinute),
            'end_time'     => self::formatMinute($this->endMinute),
            'active'       => $this->active,
        ];
    }

    /** ۱۴۴۰ به «۲۴:۰۰» تبدیل می‌شود، نه «۰۰:۰۰» — پایان روز است نه آغازش. */
    public static function formatMinute(int $minute): string
    {
        return sprintf('%02d:%02d', intdiv($minute, 60), $minute % 60);
    }
}
