<?php

namespace App\Livewire\Configurations\Envs;

use App\Models\Environments\Env;
use App\Models\Monitoring\Log as MonitoringLog;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
use Livewire\Component;

/**
 * Crear un uso del entorno.
 *
 * **Lo que había: nada.** `pro`, `pre`, `develop` y `local` eran cuatro cadenas escritas en
 * una constante de PHP, así que añadir un uso —«staging», «formación», «piloto»— era tocar
 * código y desplegar, y decidir cuáles se ven de entrada en el listado tampoco tenía
 * pantalla. Es el mismo patrón que ya apareció con los tipos de entorno (MGR-097) y con el
 * borrado de tipos de soporte: *funcionalidad que parecía existir y no tenía puerta*.
 *
 * **El `shortname` no es una etiqueta: es lo que manda cada Moodle.** El bloque
 * `environment.env` del payload llega como texto y `MoodleApiRequest` lo valida contra este
 * catálogo, así que un uso cuyo shortname no envía ningún plugin no se asigna a nadie —y no
 * lo dice ninguna pantalla—. Por eso el formulario lo explica.
 */
class Create extends Component
{
    public string $shortname = '';

    public string $name = '';

    public ?string $description = null;

    /** La clave de {@see Env::PALETA}. Se ofrece la primera, que es la de producción. */
    public string $color = 'verde';

    public bool $visible_por_defecto = true;

    public function mount(): void
    {
        // El permiso de la ruta no se reaplica en /livewire/update (MGR-005), y se
        // comprueba también al entrar: abrir un formulario que no se va a poder enviar es
        // una pantalla que engaña.
        $this->authorize('admin.configurations.envs.create');
    }

    protected function rules(): array
    {
        return [
            // **Minúsculas y sin espacios, y no es cosmética.** Este valor viaja en el
            // payload de la API y se compara tal cual: `Pro` y `pro` serían dos usos
            // distintos para la base y el mismo para quien lo lee.
            'shortname' => ['required', 'string', 'max:20', 'regex:/^[a-z0-9_-]+$/',
                // Cuenta también los borrados, igual que en los tipos: `envs.shortname`
                // lleva un `unique()` normal, que no distingue borrado lógico. Excluirlos
                // aquí solo movería el fallo a una excepción de la base.
                Rule::unique('envs', 'shortname')],
            'name' => ['required', 'string', 'max:60'],
            'description' => ['nullable', 'string', 'max:1000'],
            'color' => ['required', 'string', Rule::in(array_keys(Env::PALETA))],
            'visible_por_defecto' => ['boolean'],
        ];
    }

    protected function messages(): array
    {
        return [
            'shortname.regex' => 'Solo minúsculas, números, guion y guion bajo. Este valor lo manda el plugin del cliente en su sync y se compara tal cual: con una mayúscula, «Pro» y «pro» serían dos usos distintos.',
            'shortname.unique' => 'Ese shortname ya está en el catálogo — y sigue ocupado aunque el uso que lo tenía esté borrado, porque el índice de la base no distingue borrados.',
        ];
    }

    public function store()
    {
        $this->authorize('admin.configurations.envs.create');

        $datos = $this->validate();

        $paleta = Env::PALETA[$datos['color']];

        $uso = Env::create([
            'shortname' => $datos['shortname'],
            'name' => $datos['name'],
            'description' => $datos['description'],
            'color_text' => $paleta['texto'],
            'color_bg' => $paleta['fondo'],
            'visible_por_defecto' => $datos['visible_por_defecto'],
            // Al final de la lista: el orden decide en qué orden salen los botones del
            // filtro, y meter un uso nuevo en medio movería los que ya conoce la gente.
            'orden' => (int) (Env::withTrashed()->max('orden') ?? 0) + 10,
        ]);

        MonitoringLog::db(
            'info',
            '16037',
            'Uso de entorno creado: ' . $uso->name . ' (' . $uso->shortname . ')'
            . ' (por ' . (Auth::user()?->name ?? 'desconocido') . ')',
            'Env',
            (string) $uso->id
        );

        session()->flash('success', 'Uso «' . $uso->name . '» creado. '
            . 'Los entornos quedarán con este uso cuando su plugin mande «' . $uso->shortname . '» '
            . 'en el sync, y ya se puede elegir en los formularios de alta y edición.');

        return $this->redirect(route('configurations.catalogs'), navigate: true);
    }

    public function render()
    {
        return view('livewire.configurations.envs.form', [
            'paleta' => Env::PALETA,
            'editando' => null,
        ])->layout('layouts.clean');
    }
}
