<?php

use App\Models\System\Config;
use App\Services\System\Settings;
use Illuminate\Database\Migrations\Migration;

/**
 * Los umbrales de los límites de la API, editables desde el panel.
 *
 * Estaban solo en el `.env`. Con el modo observación activado eso era una
 * contradicción: se observa **para afinar los topes**, y afinarlos pedía entrar al
 * servidor, editar un fichero y limpiar la caché de configuración. La consecuencia
 * previsible es que nadie los afina y se acaba cortando con el número inventado del
 * primer día, que es exactamente lo que el modo observación existe para evitar.
 *
 * Las filas se crean **vacías (0)**, no con los valores actuales. Un 0 significa "no
 * puesto" y hace que el valor siga saliendo de `config/api.php`. Es deliberado:
 *
 * - Si se copiaran aquí los números del `.env`, el `.env` dejaría de tener efecto sin
 *   que nadie se enterara, y quedarían dos sitios diciendo cosas distintas.
 * - Y en una instalación nueva el `.env` sigue siendo el punto de partida.
 *
 * La pantalla muestra el valor efectivo con su origen, así que "vacío" no es un hueco:
 * es "el del fichero, y estos son".
 */
return new class extends Migration
{
    /**
     * @return array<string, array{0: string, 1: string}>
     */
    private function claves(): array
    {
        return [
            Settings::LIMITE_FALLOS => [
                'Límites de la API → Fallos por IP',
                'Respuestas 401/403 desde una misma IP antes de considerarla bloqueada. El '
                    . 'tráfico legítimo lleva token válido y no acumula aquí. 0 = usar el valor '
                    . 'del fichero de configuración.',
            ],
            Settings::LIMITE_FALLOS_VENTANA => [
                'Límites de la API → Ventana de los fallos (segundos)',
                'Cuánto tiempo se cuentan los fallos antes de olvidarlos. 0 = usar el valor del '
                    . 'fichero de configuración.',
            ],
            Settings::LIMITE_PETICIONES => [
                'Límites de la API → Techo de peticiones por IP',
                'Todas las peticiones, con token válido o sin él. Es una red de seguridad, no el '
                    . 'límite que corta a diario. 0 = usar el valor del fichero de configuración.',
            ],
            Settings::LIMITE_PETICIONES_VENTANA => [
                'Límites de la API → Ventana del techo (segundos)',
                'Cuánto tiempo se cuentan las peticiones antes de olvidarlas. 0 = usar el valor '
                    . 'del fichero de configuración.',
            ],
            Settings::LIMITE_MARGEN => [
                'Límites de la API → Margen de aviso (%)',
                'Porcentaje del tope a partir del cual ya se registra y se avisa, para poder '
                    . 'arreglarlo antes de cortar a nadie. 50 = a la mitad. 0 = usar el valor del '
                    . 'fichero de configuración.',
            ],
        ];
    }

    public function up(): void
    {
        foreach ($this->claves() as $clave => [$nombre, $descripcion]) {
            Config::updateOrCreate(
                [
                    'model' => Settings::AMBITO,
                    'model_id' => '0',
                    'shortname' => $clave,
                ],
                [
                    'name' => $nombre,
                    'type' => 'text',
                    'mode' => 'wr',
                    'permission' => 'admin.configs.edit',
                    'desc' => $descripcion,
                    // Si la fila ya existe con un valor puesto, se respeta: una migración
                    // no debe pisar una decisión que alguien ya tomó en producción.
                    'value' => Config::where('model', Settings::AMBITO)
                        ->where('shortname', $clave)
                        ->value('value') ?? '0',
                ]
            );
        }
    }

    public function down(): void
    {
        Config::whereIn('shortname', array_keys($this->claves()))->forceDelete();
    }
};
