<?php

namespace App\Appointment\Booking\Entity;

use App\Appointment\Booking\Repository\AppointmentSegmentRepository;
use App\Appointment\Entity\Appointment;
use Doctrine\ORM\Mapping as ORM;

/**
 * بخش ثبت‌شدهٔ یک نوبت — عکسِ لحظهٔ ثبت از برنامه‌ای که تسک ۰۵ ساخته بود.
 *
 * فرزند aggregate با ریشهٔ {@see Appointment}. عمداً کپی است نه ارجاع به
 * `SegmentTemplate`: الگو فردا عوض می‌شود و نوبتِ دیروز باید همان چیزی بماند که
 * بیمار رزرو کرده.
 */
#[ORM\Entity(repositoryClass: AppointmentSegmentRepository::class)]
#[ORM\Table(name: 'appointment_segments')]
#[ORM\Index(columns: ['appointment_id', 'sequence'], name: 'idx_appointment_segment_seq')]
class AppointmentSegment
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

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

    #[ORM\Column(type: 'smallint')]
    private int $sequence;

    #[ORM\Column(type: 'string', length: 150)]
    private string $name;

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

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

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

    public function __construct(
        Appointment $appointment,
        int $sequence,
        string $name,
        int $startsAt,
        int $endsAt,
        bool $patientPresent = true,
    ) {
        if ($endsAt <= $startsAt) {
            throw new \InvalidArgumentException('Segment end must be after its start.');
        }

        $this->appointment    = $appointment;
        $this->sequence       = $sequence;
        $this->name           = $name;
        $this->startsAt       = $startsAt;
        $this->endsAt         = $endsAt;
        $this->patientPresent = $patientPresent;
    }

    public function getId(): ?int                 { return $this->id; }
    public function getAppointment(): Appointment { return $this->appointment; }
    public function getSequence(): int            { return $this->sequence; }
    public function getName(): string             { return $this->name; }
    public function getStartsAt(): int            { return $this->startsAt; }
    public function getEndsAt(): int              { return $this->endsAt; }
    public function isPatientPresent(): bool      { return $this->patientPresent; }

    public function toArray(): array
    {
        return [
            'sequence'         => $this->sequence,
            'name'             => $this->name,
            'starts_at'        => $this->startsAt,
            'ends_at'          => $this->endsAt,
            'duration_minutes' => intdiv($this->endsAt - $this->startsAt, 60),
            'patient_present'  => $this->patientPresent,
        ];
    }
}
