<?php

namespace App\Cancellation\Entity;

use App\Appointment\Entity\Appointment;
use App\Auth\Entity\User;
use App\Cancellation\Repository\NoShowRecordRepository;
use App\Patient\Entity\PatientRecord;
use App\Shared\Tenant\TenantOwnedTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;

/**
 * یک بار عدم حضور — جدول جدا، نه شمارنده روی بیمار.
 *
 * همان استدلال دفتر اعتبار تسک ۱۱: شمارنده «چه زمانی و کدام نوبت» را از دست می‌دهد و
 * پنجرهٔ ۱۲ ماهه را غیرقابل محاسبه می‌کند. بیماری که سه سال پیش سه بار نیامده، امروز
 * پرریسک نیست.
 */
#[ORM\Entity(repositoryClass: NoShowRecordRepository::class)]
#[ORM\Table(name: 'no_show_records')]
#[ORM\UniqueConstraint(name: 'uniq_no_show_appointment', columns: ['appointment_id'])]
#[ORM\Index(columns: ['patient_record_id', 'recorded_at'], name: 'idx_no_show_patient')]
#[ORM\Index(columns: ['entity_type', 'entity_id', 'recorded_at'], name: 'idx_no_show_tenant')]
class NoShowRecord
{
    use TenantOwnedTrait;

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

    #[ORM\Column(type: 'string', length: 36, unique: true)]
    private string $uuid;

    #[ORM\ManyToOne(targetEntity: PatientRecord::class)]
    #[ORM\JoinColumn(name: 'patient_record_id', nullable: false, onDelete: 'CASCADE')]
    private PatientRecord $patientRecord;

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

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

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(name: 'recorded_by', nullable: true, onDelete: 'SET NULL')]
    private ?User $recordedBy = null;

    public function __construct(PatientRecord $patientRecord, Appointment $appointment, ?User $recordedBy = null, ?int $at = null)
    {
        $this->uuid          = Uuid::v4()->toRfc4122();
        $this->patientRecord = $patientRecord;
        $this->appointment   = $appointment;
        $this->recordedBy    = $recordedBy;
        $this->recordedAt    = $at ?? time();

        $this->assignTenantPair($appointment->getEntityType(), $appointment->getEntityId());
    }

    public function getId(): ?int                     { return $this->id; }
    public function getUuid(): string                 { return $this->uuid; }
    public function getPatientRecord(): PatientRecord { return $this->patientRecord; }
    public function getAppointment(): Appointment     { return $this->appointment; }
    public function getRecordedAt(): int              { return $this->recordedAt; }
    public function getRecordedBy(): ?User            { return $this->recordedBy; }

    /** @return array<string, mixed> */
    public function toArray(): array
    {
        return [
            'uuid'             => $this->uuid,
            'appointment_uuid' => $this->appointment->getUuid(),
            'slot_start'       => $this->appointment->getSlotStart(),
            'recorded_at'      => $this->recordedAt,
        ];
    }
}
