<?php

namespace Tests\Feature\Products;

use App\Livewire\Js\FileUpload as JsFileUpload;
use App\Livewire\Scss\FileUpload as ScssFileUpload;
use App\Models\Auth\User;
use App\Models\Js\JsVersion;
use App\Models\Products\Product;
use App\Models\Scss\ScssFile;
use App\Models\Scss\ScssVersion;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Cache;
use Livewire\Livewire;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

/**
 * Al subir SCSS o JS **la carpeta se descarta**, y ahora se dice (MGR-095).
 *
 * Se guarda solo el nombre base y sin extensión: `utils/helpers.scss` se guardaría como
 * `helpers`. Eso no cambia —para un árbol con dependencias está el bundle SCSS-CDN, que sí
 * conserva la ruta relativa, y duplicar esa capacidad aquí serían dos formas de hacer lo
 * mismo—. Lo que estaba mal era **la expectativa**: la página afirmaba que «al subir se
 * respeta la estructura de carpetas» y enseñaba un árbol como ejemplo válido.
 *
 * ## Lo que se intentó y no se puede hacer
 *
 * El primer arreglo detectaba los nombres con carpeta para decir en qué se quedaban, y **el
 * test lo dejó vacío**: el navegador no manda la ruta. Con `<input multiple>` envía solo el
 * nombre base, y con `webkitdirectory` la ruta relativa viaja en una propiedad de JavaScript
 * que no forma parte del `multipart`. O sea que `getClientOriginalName()` no puede traerla
 * nunca, y aquel aviso no podía dispararse.
 *
 * Se quitó. Un aviso que no puede saltar es peor que no tenerlo: hace creer que el caso está
 * cubierto. Lo que queda es lo que el propio issue proponía y sí funciona — decirlo en la
 * pantalla, siempre, antes de subir nada.
 */
class SubidaSinCarpetasTest extends TestCase
{
    use RefreshDatabase;

    private function admin(): User
    {
        $rol = Role::firstOrCreate(['name' => 'Admin', 'guard_name' => 'web']);

        foreach (['admin.products.index', 'admin.products.show', 'admin.scss.create', 'admin.js.create',
                  'admin.scss.files.upload', 'admin.js.files.upload'] as $nombre) {
            $rol->givePermissionTo(Permission::firstOrCreate(
                ['name' => $nombre, 'guard_name' => 'web'],
                ['model' => 'products', 'description' => $nombre]
            ));
        }

        $user = User::factory()->create();
        $user->assignRole($rol);
        $this->actingAs($user);

        Cache::flush();

        return $user;
    }

    private function producto(string $slug): Product
    {
        return Product::create(['name' => 'Producto ' . $slug, 'slug' => $slug, 'actived' => true]);
    }

    private function versionDeScss(Product $producto): ScssVersion
    {
        return ScssVersion::create([
            'product_id' => $producto->id, 'version' => '2026010100',
            'created_by' => 1, 'updated_by' => 1,
        ]);
    }

    public function test_la_pantalla_lo_advierte_antes_de_subir_nada(): void
    {
        // **Es el arreglo.** Enterarse de que las carpetas no se guardan después de subir un
        // árbol de veinte ficheros es tarde, y la pantalla decía justo lo contrario.
        $this->admin();

        $producto = $this->producto('theme_fresk');

        Livewire::test(ScssFileUpload::class, [
            'product' => $producto,
            'scssVersion' => $this->versionDeScss($producto),
        ])
            ->assertSee('nombre, sin carpeta')
            // Con el ejemplo, que es lo que lo hace entendible de un vistazo.
            ->assertSee('utils/helpers.scss')
            // Y diciendo dónde sí se conserva el árbol, que es la pregunta siguiente.
            ->assertSee('bundle SCSS-CDN');
    }

    public function test_en_js_la_pantalla_lo_advierte_igual(): void
    {
        // El gemelo tenía el mismo aplanamiento y la misma página mintiendo.
        $this->admin();

        $producto = $this->producto('theme_fresk');

        $version = JsVersion::create([
            'product_id' => $producto->id, 'version' => '2026010100',
            'created_by' => 1, 'updated_by' => 1,
        ]);

        Livewire::test(JsFileUpload::class, ['product' => $producto, 'jsVersion' => $version])
            ->assertSee('nombre, sin carpeta')
            ->assertSee('bundle SCSS-CDN');
    }

    public function test_un_duplicado_avisa_de_que_puede_ser_otro_archivo(): void
    {
        // «Ya existe» se lee como «estás resubiendo el mismo», y con los nombres aplanados
        // puede ser otro distinto que estaba en otra carpeta. No se puede saber cuál de los
        // dos casos es —la ruta no llega—, así que se avisa del que nadie espera.
        $this->admin();

        $producto = $this->producto('theme_fresk');
        $version = $this->versionDeScss($producto);

        ScssFile::create([
            'scss_version_id' => $version->id,
            'filename' => 'helpers',
            'content' => '// el que ya estaba',
            'created_by' => 1,
        ]);

        Livewire::test(ScssFileUpload::class, ['product' => $producto, 'scssVersion' => $version])
            ->set('uploadedFiles', [UploadedFile::fake()->createWithContent('helpers.scss', '// el nuevo')])
            ->assertSee('Duplicado')
            ->assertSee('puede ser otro archivo distinto');
    }

    public function test_el_nombre_se_guarda_aplanado_y_sin_extension(): void
    {
        // El comportamiento que la pantalla ahora describe, fijado: si algún día alguien
        // decide soportar carpetas aquí, este test se lo dirá en vez de dejar la frase de la
        // pantalla mintiendo al revés.
        $this->admin();

        $producto = $this->producto('theme_fresk');
        $version = $this->versionDeScss($producto);

        Livewire::test(ScssFileUpload::class, ['product' => $producto, 'scssVersion' => $version])
            ->set('uploadedFiles', [UploadedFile::fake()->createWithContent('helpers.scss', '// contenido')])
            ->call('confirmUpload');

        $this->assertSame(
            'helpers',
            ScssFile::where('scss_version_id', $version->id)->value('filename'),
            'el nombre se guarda sin extensión'
        );
    }
}
