<?php

namespace Modules\NX600Lab\Entities\Services;

use Illuminate\Support\Facades\DB;
use Modules\NX600Lab\Adapters\Nx600Adapter;
use Modules\NX600Lab\Contracts\LabAdapterInterface;

/**
 * Resolves a LabAdapterInterface for a business. Adapters self-register at
 * boot via $registry->register(); the registry then matches a provider
 * config row from nx_lab_providers and returns the right adapter.
 *
 * Default: Nx600Adapter so existing installs work without any setup.
 */
class LabProviderRegistry
{
    /** @var array<string, callable(int $businessId): LabAdapterInterface> */
    private array $factories = [];

    public function __construct()
    {
        // Built-in NX600 adapter is always registered.
        $this->register('nx600', fn(int $bid) => new Nx600Adapter($bid));
    }

    public function register(string $key, callable $factory): void
    {
        $this->factories[$key] = $factory;
    }

    /** All known adapter keys (for the settings UI). */
    public function knownKeys(): array
    {
        return array_keys($this->factories);
    }

    /**
     * Return the active adapter for a business. Looks up nx_lab_providers
     * for an enabled row marked is_default=true; otherwise falls back to
     * NX600 so legacy installs keep working.
     */
    public function for(int $businessId): LabAdapterInterface
    {
        $row = DB::table('nx_lab_providers')
            ->where('business_id', $businessId)
            ->where('enabled', true)
            ->orderByDesc('is_default')->orderByDesc('id')
            ->first();

        $key = $row->key ?? 'nx600';
        if (!isset($this->factories[$key])) {
            $key = 'nx600';
        }
        return ($this->factories[$key])($businessId);
    }
}
