<?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 = [];

    /**
     * Register a citizenship module.
     */
    public function register(string $countryCode, CitizenshipInterface $module): void
    {
        $this->modules[strtoupper($countryCode)] = $module;
    }

    /**
     * Get a module by country code.
     */
    public function get(string $countryCode): ?CitizenshipInterface
    {
        $code = strtoupper($countryCode);

        if (isset($this->modules[$code])) {
            return $this->modules[$code];
        }

        // Auto-load from Modules directory
        $module = $this->loadModule($code);
        if ($module) {
            $this->modules[$code] = $module;
            return $module;
        }

        // Fallback to Generic module
        return $this->loadModule('Generic');
    }

    /**
     * Check if a module exists for the given country.
     */
    public function has(string $countryCode): bool
    {
        return $this->get($countryCode) !== null;
    }

    /**
     * List all available modules.
     */
    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;
    }

    /**
     * Auto-load a module from the Modules directory.
     */
    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;
    }

    /**
     * Modül config'i: anahtarlar modülün getConfigFields()'inden (dosya),
     * value'lar module_settings'ten merge (ModuleConfig::resolved, PRC-655).
     * Eski `citizenship_{code}_*` legacy settings okuması kaldırıldı; admin
     * config'i /admin/citizenship-modules (veya verification ülke-ayarları
     * modül-config alt-formu) → module_settings'e yazar.
     */
    protected function getModuleConfig(string $countryCode): array
    {
        $name = strtolower($countryCode);

        return \App\Helpers\ModuleConfig::resolved('citizenship', $name, $this->getConfigFields($name));
    }

    // ─── ManageableModuleManager (PRC-327) ──────────────────────────────

    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
    {
        // PRC-655 — modülü config'SİZ doğrudan örnekle (loadModule DEĞİL):
        // loadModule → getModuleConfig → getConfigFields döngüsünü (recursion) kırar.
        // Field bildirimi config'e bağlı olmadığından boş config yeterli.
        $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());
        }
    }
}
