<?php

namespace App\Rules;

use App\Services\Features\HtmlSanitizer;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

/**
 * Avisa al autor de que lo que acaba de pegar **no se va a ver** (MGR-002).
 *
 * **El problema, y no es de seguridad.** Se puede insertar un `iframe` en el HTML
 * enriquecido de una funcionalidad —un vídeo de YouTube, por ejemplo—, el editor lo acepta
 * sin protestar y en el Moodle del cliente **no se pinta nunca**. Sin error, sin hueco: el
 * bloque desaparece. El autor se entera cuando alguien mira la pantalla del producto, que
 * puede ser una semana después.
 *
 * **Y no se puede permitir relajando nuestra lista**, que es lo que uno intenta primero.
 * Hay dos saneadores en serie: el nuestro y el del plugin, que pasa lo recibido por
 * `format_text()` con el HTMLPurifier del **core de Moodle**, y ése no activa
 * `HTML.SafeIframe`. Así que quita cualquier `iframe`, incluidos los de YouTube y Vimeo.
 * Aunque abriéramos la puerta de aquí, la de allí sigue cerrada y no es nuestra.
 *
 * Lo único que se puede arreglar desde el Manager es **cuándo se entera el autor**: al
 * guardar, en lugar de nunca.
 *
 * **Por qué corta y no solo avisa.** Un aviso después de guardar se cierra sin leerlo y el
 * vídeo se queda perdido igual; y guardar una funcionalidad a la que le falta el vídeo es
 * peor que no guardarla, porque parece que salió bien. Cortar es seguro **porque el
 * contenido ya guardado está limpio**: las dos puertas —`Features\Create` y `Features\Edit`—
 * pasan por el saneador desde siempre, así que esto no puede bloquear a nadie que esté
 * editando algo antiguo. Solo alcanza a lo que se pega ahora.
 *
 * El mensaje dice **qué hacer**, no solo qué está mal: para vídeo la vía es Tutoriales, que
 * es un tipo de contenido aparte con `platform` + `video_id`, y el plugin monta el embed en
 * una plantilla propia que no pasa por el saneado de HTML remoto.
 */
class SinEtiquetasQueElMoodleBorra implements ValidationRule
{
    /**
     * Las que tienen alternativa, y cuál es.
     *
     * Solo estas dos llevan consejo porque son las que un autor usa **queriendo**. Nadie
     * pega un `<script>` maquetando una funcionalidad; un vídeo de YouTube, todos los días.
     *
     * @var array<string, string>
     */
    private const ALTERNATIVAS = [
        'iframe' => 'para vídeo, créalo como Tutorial: ahí se guarda la plataforma y el identificador, y el plugin lo monta con su propia plantilla',
        'object' => 'para vídeo, créalo como Tutorial',
        'embed' => 'para vídeo, créalo como Tutorial',
    ];

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! is_string($value)) {
            return;
        }

        $encontradas = HtmlSanitizer::prohibidasPresentes($value);

        if ($encontradas === []) {
            return;
        }

        $etiquetas = implode(', ', array_map(fn ($e) => '<' . $e . '>', $encontradas));

        $consejo = '';
        foreach ($encontradas as $etiqueta) {
            if (isset(self::ALTERNATIVAS[$etiqueta])) {
                $consejo = ' — ' . self::ALTERNATIVAS[$etiqueta];
                break;
            }
        }

        $fail(
            'El contenido incluye ' . $etiquetas . ', y el Moodle del cliente lo elimina al '
            . 'pintar la página: no se vería nada y tampoco daría error' . $consejo . '. '
            . 'Quítalo para poder guardar.'
        );
    }
}
