<?php

namespace Tests\Feature\Tutorials;

use App\Models\Auth\User;
use App\Models\Products\Product;
use App\Models\Tutorials\Tutorial;
use App\Models\Tutorials\TutorialVersion;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Spatie\Permission\Models\Permission;
use Tests\TestCase;

/**
 * El preview de un tutorial es una pantalla interna (MGR-012).
 *
 * La ruta estaba dentro del grupo `auth` pero **sin `permission:`**, y el controlador
 * no comprobaba nada: cualquier usuario autenticado, de cualquier rol, veía cualquier
 * tutorial poniendo su id en la URL. Y el preview **no filtra por estado** —para eso
 * existe—, así que era el único sitio del sistema donde se veía un tutorial en
 * borrador.
 *
 * Lo que se filtraba de verdad es el `videoid`: un vídeo "oculto" de YouTube o Vimeo
 * no tiene más protección que su identificador, así que la URL **es** la contraseña.
 *
 * No era un olvido, era una decisión a medias: el comentario del código decía "puede
 * ser público o con auth según necesidad". Se decidió que es interno.
 */
class PreviewTest extends TestCase
{
    use RefreshDatabase;

    private const PERMISO = 'admin.tutorials.version.show';

    private function usuario(array $permisos): User
    {
        foreach ($permisos as $nombre) {
            Permission::firstOrCreate(
                ['name' => $nombre, 'guard_name' => 'web'],
                ['model' => 'tutorials', 'description' => $nombre]
            );
        }

        $user = User::factory()->create();

        if ($permisos !== []) {
            $user->givePermissionTo($permisos);
        }

        $this->actingAs($user);
        Cache::flush();

        return $user;
    }

    private function tutorial(string $status = 'draft'): Tutorial
    {
        // Sufijo por llamada: `products.slug` es único y un test recorre los tres
        // estados creando un tutorial en cada vuelta.
        $sufijo = \App\Models\Products\Product::count() + 1;

        $producto = Product::create([
            'name' => 'Producto Tutorial ' . $sufijo,
            'slug' => 'theme_tutorial' . $sufijo,
            'shortname' => 'tut' . $sufijo,
        ]);

        $version = TutorialVersion::create([
            'product_id' => $producto->id,
            'version' => '2026010100',
            'created_by' => auth()->id(),
        ]);

        return Tutorial::create([
            'tutorial_version_id' => $version->id,
            'videoid' => 'dQw4w9WgXcQ',
            'platform' => 'youtube',
            'title' => 'Cómo configurar el producto',
            'desc' => 'Un vídeo que todavía no está publicado.',
            'status' => $status,
            'sort_order' => 1,
            'created_by' => auth()->id(),
        ]);
    }

    public function test_un_usuario_sin_el_permiso_no_ve_el_preview(): void
    {
        // El caso que abría el agujero: estar logueado bastaba.
        $this->usuario(['admin.dashboard.index']);
        $tutorial = $this->tutorial();

        $this->get(route('tutorials.preview', $tutorial))->assertForbidden();
    }

    public function test_tampoco_ve_el_identificador_del_video(): void
    {
        // Lo que de verdad se protege: con el `videoid` de un vídeo oculto, cualquiera
        // puede verlo y compartirlo fuera, sin pasar por el Manager.
        $this->usuario(['admin.dashboard.index']);
        $tutorial = $this->tutorial();

        $respuesta = $this->get(route('tutorials.preview', $tutorial));

        $this->assertStringNotContainsString('dQw4w9WgXcQ', $respuesta->getContent());
    }

    public function test_sin_sesion_manda_al_login(): void
    {
        // Se crea el tutorial con un usuario y luego se cierra la sesión, porque
        // `created_by` necesita a alguien.
        $this->usuario([self::PERMISO]);
        $tutorial = $this->tutorial();

        auth()->logout();

        $this->get(route('tutorials.preview', $tutorial))->assertRedirect('/login');
    }

    public function test_con_el_permiso_se_ve_el_video(): void
    {
        $this->usuario([self::PERMISO]);
        $tutorial = $this->tutorial();

        $this->get(route('tutorials.preview', $tutorial))
            ->assertOk()
            ->assertSee('Cómo configurar el producto')
            ->assertSee('dQw4w9WgXcQ', false);
    }

    public function test_un_borrador_se_puede_previsualizar(): void
    {
        // Es el sentido de la pantalla y no debe cambiar: se revisa ANTES de publicar.
        // La API sigue sirviendo solo los publicados, que es otra cosa.
        $this->usuario([self::PERMISO]);

        foreach (['draft', 'published', 'archived'] as $estado) {
            $tutorial = $this->tutorial($estado);

            $this->get(route('tutorials.preview', $tutorial))
                ->assertOk()
                ->assertSee('Cómo configurar el producto');
        }
    }
}
