<?php
 namespace App\Core\Citizenship; use App\Core\Module\ConfigFieldNormalizer; use App\Core\Module\ManageableModuleManager; use App\Core\Module\TestResult; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Log; class CitizenshipManager implements ManageableModuleManager { protected array $modules = []; public function register(string $countryCode, CitizenshipInterface $module): void { $this->modules[strtoupper($countryCode)] = $module; } public function get(string $countryCode): ?CitizenshipInterface { $code = strtoupper($countryCode); if (isset($this->modules[$code])) { return $this->modules[$code]; } $module = $this->loadModule($code); if ($module) { $this->modules[$code] = $module; return $module; } return $this->loadModule('Generic'); } public function has(string $countryCode): bool { return $this->get($countryCode) !== null; } public function listAvailableModules(): array { $modulesPath = app_path('Modules/Citizenship'); if (!is_dir($modulesPath)) { return []; } $modules = []; $dirs = array_filter(glob($modulesPath . '/*'), 'is_dir'); foreach ($dirs as $dir) { $countryCode = basename($dir); $module = $this->get($countryCode); if ($module) { $modules[$countryCode] = $module->getModuleInfo(); } } return $modules; } protected function loadModule(string $countryCode): ?CitizenshipInterface { $className = "App\\Modules\\Citizenship\\{$countryCode}\\{$countryCode}"; if (!class_exists($className)) { return null; } try { $config = $this->getModuleConfig($countryCode); $module = new $className($config); if ($module instanceof CitizenshipInterface) { return $module; } } catch (\Exception $e) { Log::error("Failed to load citizenship module: {$countryCode}", [ 'error' => $e->getMessage(), ]); } return null; } protected function getModuleConfig(string $countryCode): array { $name = strtolower($countryCode); return \App\Helpers\ModuleConfig::resolved('citizenship', $name, $this->getConfigFields($name)); } public function discover(): array { $modulesPath = app_path('Modules/Citizenship'); if (! is_dir($modulesPath)) { return []; } $out = []; foreach (array_filter(glob($modulesPath . '/*'), 'is_dir') as $dir) { $countryCode = basename($dir); $module = $this->loadModule($countryCode); if (! $module) { continue; } $info = method_exists($module, 'getModuleInfo') ? $module->getModuleInfo() : []; $out[] = [ 'name' => strtolower($countryCode), 'label' => $info['name'] ?? $info['label'] ?? $countryCode, ]; } return $out; } public function getConfigFields(string $name): array { $code = strtoupper($name); $class = "App\\Modules\\Citizenship\\{$code}\\{$code}"; if (! class_exists($class)) { return []; } try { $instance = new $class([]); $legacy = method_exists($instance, 'getConfigFields') ? $instance->getConfigFields() : []; } catch (\Throwable $e) { return []; } return ConfigFieldNormalizer::normalize(is_array($legacy) ? $legacy : []); } public function test(string $name, array $config): TestResult { $module = $this->loadModule(strtoupper($name)); if (! $module) { return TestResult::failure("Module not loadable: {$name}"); } if (! method_exists($module, 'testConnection')) { return TestResult::success('Module loaded (no testConnection available).'); } try { $result = $module->testConnection($config); $success = (bool) ($result['success'] ?? false); $message = (string) ($result['message'] ?? $result['error'] ?? ($success ? 'OK' : 'failed')); return new TestResult($success, $message); } catch (\Throwable $e) { return TestResult::failure($e->getMessage()); } } } 