<?php

namespace Modules\PortalApi\Contracts;

/**
 * A vertical's implementation of public appointment booking.
 *
 * PortalApi owns the shared, vertical-agnostic parts of the public booking flow
 * (brand resolution + the public_booking/booking_otp gates, phone OTP, the honeypot,
 * and find-or-create of the App\Contact). Everything that differs per business type —
 * the "subject" (a pet vs a patient), the appointment table, and how free slots are
 * computed — lives behind this contract.
 *
 * VetClinic and ClinicCore each register a driver into {@see \Modules\PortalApi\Support\BookingDriverRegistry}
 * from their service provider; the registry picks the one that serves a given business.
 */
interface BookingDriver
{
    /** Stable vertical key, e.g. 'vet_clinic' | 'medical_clinic'. */
    public function vertical(): string;

    /** Does this driver serve the given business? Must be deterministic + exclusive. */
    public function supports(int $businessId): bool;

    /** Label for the subject field shown on the public form ("Pet" / "Patient"). */
    public function subjectLabel(): string;

    /** Whether the form should collect a species (vet: yes, human clinic: no). */
    public function collectsSpecies(): bool;

    /**
     * Active, bookable doctors for the business.
     * @return array<int, array{id:int, name:string}>
     */
    public function doctors(int $businessId): array;

    /**
     * Open slots for a date. Returns at least a `slots` key in the shape the
     * booking page consumes: [{start, label, doctor_name, available}, ...].
     *
     * @return array{slots: array<int, array{start:string,label:string,doctor_name:string,available:bool}>}
     */
    public function availability(int $businessId, \DateTimeInterface $date, ?int $doctorId): array;

    /**
     * Create the vertical subject (pet/patient) for an existing contact, then a
     * PENDING appointment. The shared controller has already resolved/created the
     * contact and verified OTP. Returns at least ['ref_no' => string].
     *
     * @param array $data validated booking input: subject_name, species, date, time, doctor_id, reason
     * @return array{ref_no:string}
     */
    public function createPendingBooking(int $businessId, int $contactId, array $data): array;
}
