<?php

namespace Modules\ClinicCore\Entities;

use Illuminate\Database\Eloquent\Model;
use App\Contact;
use Carbon\Carbon;
use Modules\ClinicCore\Entities\ClcMedicalReport;

class ClcPatient extends Model
{
    protected $table = 'clc_patients';
    protected $guarded = ['id'];

    protected $casts = [
        'neutered'  => 'boolean',
        'deceased'  => 'boolean',
        'dob'       => 'date',
    ];

    /**
     * The human patient is an ERP App\Contact. `contact()` is the canonical
     * accessor; `owner()` is kept as a back-compat alias for code cloned from
     * VetClinic (where the contact was the pet's owner).
     */
    public function contact()
    {
        return $this->belongsTo(Contact::class, 'contact_id');
    }

    public function owner()
    {
        return $this->belongsTo(Contact::class, 'contact_id');
    }

    public function preferredDoctor()
    {
        return $this->belongsTo(ClcDoctor::class, 'preferred_doctor_id');
    }

    /** Optional default specialty for this patient (no pre-enrollment needed). */
    public function defaultSpecialty()
    {
        return $this->belongsTo(ClcSpecialty::class, 'default_specialty_id');
    }

    public function ownerDetail()
    {
        return $this->belongsTo(ClcPatientContactDetail::class, 'contact_id', 'contact_id');
    }

    /**
     * Display name: the stored patient_name if set, otherwise the linked
     * contact's name. Lets the cloned views keep using $patient->patient_name
     * even though the canonical name lives on App\Contact.
     */
    public function getPatientNameAttribute($value)
    {
        return $value ?: optional($this->owner)->name;
    }

    /**
     * Effective preferred doctor id: the patient's own override, falling back
     * to the contact's general preferred doctor.
     */
    public function effectivePreferredDoctorId()
    {
        if ($this->preferred_doctor_id) {
            return $this->preferred_doctor_id;
        }
        return optional($this->ownerDetail)->preferred_doctor_id;
    }

    public function conditions()
    {
        return $this->hasMany(ClcPatientCondition::class, 'patient_id');
    }

    /**
     * P3-T1 structured clinical baseline satellites.
     *
     * Named structuredAllergies (not allergies) because clc_patients carries a
     * legacy `allergies` TEXT column — an attribute always shadows a relation
     * of the same name, so `$patient->allergies` would return the string and
     * `->count()` on it fatals (this 500'd the patient page).
     */
    public function structuredAllergies()
    {
        return $this->hasMany(ClcPatientAllergy::class, 'patient_id');
    }

    public function medications()
    {
        return $this->hasMany(ClcPatientMedication::class, 'patient_id');
    }

    public function insurances()
    {
        return $this->hasMany(ClcPatientInsurance::class, 'patient_id');
    }

    /** P3-T8 active medical-safety alerts raised for this patient. */
    public function medicalAlerts()
    {
        return $this->hasMany(ClcMedicalAlert::class, 'patient_id');
    }

    /** P3-T1 registered branch (business_locations). */
    public function registeredLocation()
    {
        return $this->belongsTo(\App\BusinessLocation::class, 'registered_location_id');
    }

    /** P3-T1 merge target: the surviving master this record was merged into. */
    public function mergedInto()
    {
        return $this->belongsTo(ClcPatient::class, 'merged_into_id');
    }

    public function appointments()
    {
        return $this->hasMany(ClcAppointment::class, 'patient_id');
    }

    /** SIFA P3-T4 trend-capable vitals readings for this patient. */
    public function vitals()
    {
        return $this->hasMany(ClcVital::class, 'patient_id')->orderByDesc('recorded_at');
    }

    public function vaccinations()
    {
        return $this->hasMany(ClcVaccination::class, 'patient_id')->orderByDesc('administered_date');
    }

    public function prescriptions()
    {
        return $this->hasMany(ClcPrescription::class, 'patient_id')->orderByDesc('prescribed_date');
    }

    public function medicalReports()
    {
        return $this->hasMany(ClcMedicalReport::class, 'patient_id')->orderByDesc('created_at');
    }

    public function getPhotoUrlAttribute()
    {
        if ($this->photo_path) {
            return asset('uploads/' . $this->photo_path);
        }
        return null;
    }

    public function getAgeAttribute()
    {
        if (!$this->dob) return null;
        return Carbon::parse($this->dob)->age;
    }

    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }
}
