<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * El catálogo de usos del entorno: `pro`, `pre`, `develop`, `local`.
 *
 * **Eran una constante en el modelo**, `Environment::ENVIRONMENTS`, con sus cuatro valores
 * escritos a mano y sus colores copiados en seis vistas. Eso significaba tres cosas:
 *
 * 1. **No se podía añadir uno** sin tocar código y desplegar. Y hay preguntas razonables
 *    —«staging», «formación», «piloto»— que hoy no tienen dónde ir.
 * 2. **Cuáles se ven de entrada en el filtro no se podía decidir.** El listado de entornos
 *    esconde los `local` porque en el parque real son ruido de desarrollo, pero eso estaba
 *    decidido en una constante de PHP y no en ninguna pantalla.
 * 3. Los colores divergían: la ficha del entorno pintaba `pro` en naranja bajo un
 *    comentario que decía «el mismo código de color que el listado».
 *
 * ## Por qué `environments.env` sigue siendo una cadena y no una clave ajena
 *
 * **Porque ese valor lo manda cada Moodle.** El bloque `environment.env` del payload de la
 * API llega como texto —`"pro"`— y `MoodleApiRequest` lo valida contra este catálogo. Con
 * una clave ajena habría que traducir en cada llamada, y una petición con un `env` que no
 * existe pasaría de «dato que no cuadra» a error de integridad.
 *
 * Así que este catálogo empareja por `shortname`, que es el valor que ya está guardado en
 * las 21 filas de `environments`. Nada que migrar en esa tabla.
 *
 * ## El orden
 *
 * `orden` no es decoración: es el orden en que salen los botones del filtro y **el orden
 * canónico de la URL**. `alternarEnv()` reordena a este orden en cada cambio para que dos
 * formas de llegar a la misma selección den el mismo enlace. Se siembra con producción
 * primero, que es lo que se mira.
 */
return new class extends Migration
{
    /**
     * Los cuatro de siempre, con los colores que ya usaba la fila del listado y con
     * `local` fuera del filtro por defecto — que es lo que hacía el código.
     */
    private const SEMILLA = [
        ['shortname' => 'pro', 'name' => 'Producción', 'orden' => 10, 'visible_por_defecto' => true,
            'color_text' => 'var(--teal-700)', 'color_bg' => 'var(--teal-100)',
            'description' => 'El sitio que usan los alumnos. Es el que se mira primero cuando algo falla.'],
        ['shortname' => 'pre', 'name' => 'PreProducción', 'orden' => 20, 'visible_por_defecto' => true,
            'color_text' => 'var(--info-500)', 'color_bg' => 'var(--info-50)',
            'description' => 'El previo de producción: donde se valida antes de subir.'],
        ['shortname' => 'develop', 'name' => 'Desarrollo', 'orden' => 30, 'visible_por_defecto' => true,
            'color_text' => 'var(--neutral-700)', 'color_bg' => 'var(--neutral-100)',
            'description' => 'Entorno de trabajo del equipo.'],
        ['shortname' => 'local', 'name' => 'Local', 'orden' => 40, 'visible_por_defecto' => false,
            'color_text' => 'var(--neutral-600)', 'color_bg' => 'var(--surface-sunken)',
            'description' => 'La máquina de alguien. En el parque real son ruido de desarrollo, '
                . 'así que no salen de entrada en el listado de entornos.'],
    ];

    public function up(): void
    {
        Schema::create('envs', function (Blueprint $table) {
            $table->id();

            // **La llave de verdad.** Es el valor que guarda `environments.env` y el que
            // manda cada Moodle en el payload, así que no puede repetirse ni cambiar a la
            // ligera: la pantalla de edición lo deja fijo cuando algún entorno lo usa.
            $table->string('shortname', 20)->unique();

            $table->string('name', 60);
            $table->text('description')->nullable();

            // Los colores como texto y no como enum: son variables del tema
            // (`var(--teal-700)`), que es lo que ya usaban las vistas, y así un uso nuevo
            // puede tomar cualquier color del sistema sin tocar código.
            $table->string('color_text', 40)->default('var(--neutral-600)');
            $table->string('color_bg', 40)->default('var(--surface-sunken)');

            // Si sale marcado de entrada en el filtro del listado de entornos.
            $table->boolean('visible_por_defecto')->default(true);

            $table->unsignedSmallInteger('orden')->default(0);

            $table->timestamps();

            // Lógico: un uso borrado por error se recupera, y los entornos que lo tengan
            // guardado en su columna `env` lo vuelven a emparejar.
            $table->softDeletes();

            $table->index(['orden', 'name']);
        });

        foreach (self::SEMILLA as $fila) {
            DB::table('envs')->insert($fila + [
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }

        // **Y los que ya estén guardados y no estén en la semilla.** En desarrollo los
        // cuatro son los de siempre, pero si en algún sitio hay un `env` escrito a mano
        // que no está en la lista, el catálogo tiene que reconocerlo: sin su fila, la
        // ficha de ese entorno pintaría el uso vacío y su formulario no podría guardarlo.
        $conocidos = array_column(self::SEMILLA, 'shortname');

        $huerfanos = DB::table('environments')
            ->whereNotNull('env')
            ->where('env', '!=', '')
            ->whereNotIn('env', $conocidos)
            ->distinct()
            ->pluck('env');

        $orden = 50;

        foreach ($huerfanos as $env) {
            DB::table('envs')->insert([
                'shortname' => mb_substr((string) $env, 0, 20),
                'name' => (string) $env,
                'description' => 'Se encontró guardado en entornos al crear el catálogo. '
                    . 'Revisa su nombre y su color.',
                'visible_por_defecto' => true,
                'orden' => $orden,
                'created_at' => now(),
                'updated_at' => now(),
            ]);

            $orden += 10;
        }
    }

    public function down(): void
    {
        Schema::dropIfExists('envs');
    }
};
