<?php

namespace Modules\PortalApi\Support;

use Modules\PortalApi\Contracts\BookingDriver;

/**
 * Registry of the per-vertical booking drivers. VetClinic + ClinicCore register
 * their driver here from their service providers; the public booking controller
 * asks the registry which driver serves a given business.
 *
 * Storage is process-static (keyed by vertical) so registrations accumulate and
 * survive regardless of how the container hands out instances — the only
 * requirement is that each module's service-provider boot() runs, which is the
 * standard module lifecycle. Keying by vertical also makes registration idempotent.
 */
class BookingDriverRegistry
{
    /** @var array<string, BookingDriver> */
    private static array $drivers = [];

    public function register(BookingDriver $driver): void
    {
        self::$drivers[$driver->vertical()] = $driver;
    }

    /** The first registered driver that serves this business, or null. */
    public function forBusiness(int $businessId): ?BookingDriver
    {
        foreach (self::$drivers as $driver) {
            try {
                if ($driver->supports($businessId)) {
                    return $driver;
                }
            } catch (\Throwable $e) {
                // A driver whose module is half-loaded (e.g. its tables aren't on
                // this project's DB) must never break resolution.
            }
        }
        return null;
    }

    /** @return BookingDriver[] */
    public function all(): array
    {
        return array_values(self::$drivers);
    }
}
