<?php

namespace App\Helpers;

use App\Models\Module;

/**
 * PRC-398 / PRC-327 — read-side helper for the new Module schema.
 *
 * Replaces flat `Setting::get('sms_twilio_api_key')` lookups with a
 * structured per-module config map. Two access patterns:
 *
 *  - `ModuleConfig::for('sms', 'twilio')` — specific module's config
 *    (returns null if disabled or absent).
 *  - `ModuleConfig::active('email')` — the single enabled module of the
 *    family with the lowest sort_order. Useful when there's a one-of-N
 *    semantic (active email driver, active currency provider).
 */
class ModuleConfig
{
    /**
     * @return array<string, string|null>|null
     */
    public static function for(string $type, string $name): ?array
    {
        $module = Module::ofType($type)
            ->enabled()
            ->where('name', $name)
            ->with('settings')
            ->first();

        return $module?->config;
    }

    public static function active(string $type): ?Module
    {
        return Module::ofType($type)
            ->enabled()
            ->orderBy('sort_order')
            ->orderBy('id')
            ->with('settings')
            ->first();
    }

    /**
     * @return array<string, string|null>|null
     */
    public static function activeConfig(string $type): ?array
    {
        return self::active($type)?->config;
    }

    /**
     * PRC-654 — çözülmüş modül config'i: ANAHTARLAR dosyadan (modülün bildirdiği
     * field'lar = $declaredFields, getConfigFields() çıktısı), VALUE'LAR
     * module_settings'ten eşlenir. Her key için: DB satırı varsa onun value'su
     * (admin boş bıraktıysa boş kalır = bilinçli tercih), yoksa field default'u,
     * o da yoksa null. Bildirilmemiş (dosyada olmayan) DB key'leri göz ardı edilir
     * — dosya anahtar otoritesidir. `enabled` filtresi YOK (config çözümü ≠ modül
     * seçimi). Böylece modül dosyasına yeni bir field eklemek anında yansır.
     *
     * @param  list<array{key:string, default?:mixed}>  $declaredFields
     * @return array<string, mixed>
     */
    public static function resolved(string $type, string $name, array $declaredFields): array
    {
        $module = Module::ofType($type)
            ->where('name', $name)
            ->with('settings')
            ->first();

        $db = $module?->config ?? []; // [key => decrypted value] — yalnız var olan satırlar

        $out = [];
        foreach ($declaredFields as $field) {
            $key = $field['key'];
            $out[$key] = array_key_exists($key, $db)
                ? $db[$key]
                : ($field['default'] ?? null);
        }

        return $out;
    }
}
