<?php

namespace Modules\ClinicCore\Entities\Contracts;

/**
 * Contract every clinical-specialty plugin module implements and registers
 * with the ClinicCore SpecialtyDriverRegistry.
 *
 * ClinicCore owns the shared engine — one patient (= App\Contact), doctors,
 * appointments, prescriptions, pharmacy, exams, consents, reminders. A
 * specialty plugin (DermatologyClinic, DentalClinic, …) owns only the
 * *differences*: specialty-specific patient fields (stored in its own 1:1
 * extension table), specialty exam sheets, and the Blade fragments injected
 * into ClinicCore's shared patient/appointment screens.
 *
 * Most of the ~45 supported specialties are pure data (a clc_specialties row)
 * and need NO driver. Only structurally-unique specialties register one.
 *
 * @see \Modules\ClinicCore\Entities\Services\SpecialtyDriverRegistry
 */
interface ClinicSpecialtyDriver
{
    /**
     * Machine specialty key. Matches clc_specialties.code and is the registry
     * key. e.g. 'dermatology', 'dental'.
     */
    public function key(): string;

    /**
     * Human-readable specialty label, e.g. 'Dermatology'.
     */
    public function label(): string;

    /**
     * FQCN of the Eloquent model for this specialty's 1:1 patient extension
     * table (keyed by clc_patient_id), or null if the specialty stores no
     * extra structured patient fields.
     *
     * @return class-string|null
     */
    public function patientProfileModel(): ?string;

    /**
     * Blade view rendered inside ClinicCore's patient create/edit form to
     * collect this specialty's extra fields, or null. Receives $patient.
     */
    public function patientFormFragment(): ?string;

    /**
     * Blade view rendered inside ClinicCore's patient show screen to display
     * this specialty's profile, or null. Receives $patient.
     */
    public function patientShowFragment(): ?string;

    /**
     * Blade view injected into ClinicCore's appointment screen when the
     * appointment's specialty matches this driver (e.g. a dental tooth chart),
     * or null. Receives $appointment.
     */
    public function appointmentFragment(): ?string;

    /**
     * Persist this specialty's extra patient fields after ClinicCore has
     * saved the shared patient record. Implementations typically upsert a row
     * in their 1:1 extension table keyed by the patient id. No-op is allowed.
     *
     * @param  \Modules\ClinicCore\Entities\ClcPatient $patient
     * @param  array $input  The full request input from the patient form.
     */
    public function persistPatientProfile($patient, array $input): void;

    /**
     * Exam-template definitions seeded for this specialty. Each entry follows
     * the clc_exam_templates/items shape the shared exam engine consumes.
     *
     * @return array<int,array<string,mixed>>
     */
    public function examTemplateSeeds(): array;

    /**
     * Terminology overrides (label key => replacement) applied on top of the
     * generic ClinicCore vocabulary when this specialty is active.
     *
     * @return array<string,string>
     */
    public function terminology(): array;

    /*
     * OPTIONAL (deliberately NOT a declared interface method, so config-only
     * specialties and existing drivers keep working): a structural driver MAY
     * implement
     *
     *     public function capabilities(): array
     *
     * returning a map like ['controlled_drugs' => true, 'perio' => true, …].
     * ClinicCore's ClinicCapabilities resolves it via method_exists ahead of
     * the clc_specialties.capabilities row and the per-business override.
     *
     * Likewise OPTIONAL: a driver MAY implement
     *
     *     public function aiGuidance(): array
     *
     * returning a list of short clinical-guidance strings (red flags, common
     * differentials, prescribing cautions) for THIS specialty. ClcAiController
     * folds them into the AI assistant's system prompt (via method_exists),
     * overriding its curated DEFAULT_GUIDANCE map for the specialty code.
     */
}
