<?php

namespace Modules\ClinicCore\Entities\Services;

use Modules\ClinicCore\Entities\ClcSpecialty;
use Modules\ClinicCore\Entities\ClcModuleSetting;

/**
 * Central resolver for clinic feature capabilities.
 *
 * Resolution order (first decisive wins):
 *   1. Per-business override — ClcModuleSetting key "capability.<key>" ('1'/'0')
 *   2. Specialty capability  — ClcSpecialty->capability(), incl. its driver override
 *      (when $specialtyId is null: true if ANY active specialty for the business
 *       declares the capability — used for business-wide features like the
 *       controlled-drug register and the sidebar menu).
 *   3. Global default        — see DEFAULTS.
 */
class ClinicCapabilities
{
    /** Global fallback when neither a business override nor a specialty value exists. */
    public const DEFAULTS = [
        'vitals'           => true,
        'ai_assist'        => true,
        'vaccinations'     => true,
        'controlled_drugs' => false,
        'imaging'          => false,
        'wellness'         => false,
        'perio'            => false,
    ];

    /**
     * Clinic-type presets — a one-click bundle of capability overrides a
     * business can apply in Settings. Each preset is a capability => bool map
     * written to clc_module_settings as capability.* overrides.
     */
    public const PRESETS = [
        'general'  => ['controlled_drugs' => false, 'vitals' => true,  'vaccinations' => true,  'imaging' => false, 'wellness' => false, 'ai_assist' => true],
        'dental'   => ['controlled_drugs' => true,  'vitals' => true,  'vaccinations' => false, 'imaging' => true,  'wellness' => false, 'ai_assist' => true,  'perio' => true],
        'aesthetic'=> ['controlled_drugs' => false, 'vitals' => true,  'vaccinations' => false, 'imaging' => false, 'wellness' => true,  'ai_assist' => true],
        'surgical' => ['controlled_drugs' => true,  'vitals' => true,  'vaccinations' => false, 'imaging' => true,  'wellness' => false, 'ai_assist' => true],
        'pediatric'=> ['controlled_drugs' => false, 'vitals' => true,  'vaccinations' => true,  'imaging' => false, 'wellness' => true,  'ai_assist' => true],
    ];

    /** Apply a named preset to a business as capability.* overrides. */
    public static function applyPreset(int $businessId, string $preset): bool
    {
        $caps = self::PRESETS[$preset] ?? null;
        if (!$caps) return false;
        foreach ($caps as $key => $on) {
            ClcModuleSetting::set($businessId, 'capability.' . $key, $on ? '1' : '0');
        }
        return true;
    }

    public static function enabled(int $businessId, ?int $specialtyId, string $key): bool
    {
        // 1. Per-business override.
        $override = ClcModuleSetting::get($businessId, 'capability.' . $key, null);
        if ($override !== null && $override !== '') {
            return (string) $override === '1';
        }

        // 2a. Specific specialty.
        if ($specialtyId) {
            $specialty = ClcSpecialty::find($specialtyId);
            if ($specialty) {
                $driverVal = self::driverCapability($specialty, $key);
                if ($driverVal !== null) return $driverVal;
                $val = $specialty->capability($key, null);
                if ($val !== null) return (bool) $val;
            }
            return self::DEFAULTS[$key] ?? false;
        }

        // 2b. Business-wide: any active specialty declaring the capability.
        $any = ClcSpecialty::forBusiness($businessId)->active()->get()
            ->contains(function ($s) use ($key) {
                $driverVal = self::driverCapability($s, $key);
                if ($driverVal !== null) return $driverVal;
                return (bool) $s->capability($key, false);
            });
        if ($any) return true;

        // 3. Global default.
        return self::DEFAULTS[$key] ?? false;
    }

    /** A structural specialty's driver MAY expose capabilities(): array. */
    private static function driverCapability(ClcSpecialty $specialty, string $key): ?bool
    {
        try {
            if (!$specialty->hasDriver()) return null;
            $driver = $specialty->driver();
            if ($driver && method_exists($driver, 'capabilities')) {
                $caps = $driver->capabilities();
                if (is_array($caps) && array_key_exists($key, $caps)) {
                    return (bool) $caps[$key];
                }
            }
        } catch (\Throwable $e) {
            // Never let driver resolution break a capability check.
        }
        return null;
    }

    /** Convenience for blades/menus: the business-wide flag. */
    public static function businessHas(int $businessId, string $key): bool
    {
        return self::enabled($businessId, null, $key);
    }
}
