<?php

namespace App\Livewire\Scss;

use App\Livewire\Traits\MuestraVersionDeArchivos;
use App\Models\Products\Product;
use App\Models\Scss\ScssFile;
use App\Models\Scss\ScssVersion;
use App\Services\Scss\ScssStorageService;
use Livewire\Component;

/**
 * Una versión de SCSS y sus archivos.
 *
 * Comparte pantalla con la de JS —eran dos ficheros de 160 líneas con un diff de 48, todas
 * nombres— a través de `MuestraVersionDeArchivos`. Lo que cambia se declara abajo.
 */
class VersionShow extends Component
{
    use MuestraVersionDeArchivos;

    public Product $product;

    public ScssVersion $scssVersion;

    public function mount(Product $product, ScssVersion $scssVersion)
    {
        $this->product = $product;

        // **La versión pertenece a este producto.** La ruta es
        // `/products/{product}/scss/{scssVersion}` y los dos llegan de la URL: sin esta
        // comprobación se podía ver la versión de otro producto poniendo su id, que es el
        // mismo IDOR que MGR-006. Los gemelos de Features, Recursos y Tutoriales ya lo
        // comprobaban; este y el de JS, no.
        abort_unless($scssVersion->product_id === $product->id, 404);

        // Sin `load('files')`: los archivos se consultan en el trait con su peso calculado
        // en SQL, y cargarlos aquí traía el contenido entero de cada uno para nada.
        $this->scssVersion = $scssVersion->load('creator');
    }

    protected function fichaDeLaVersion(): array
    {
        return [
            'clave' => 'scss',
            'version' => $this->scssVersion,
            'elemento' => 'archivo',
            'elementos' => 'archivos',
            'rutaListado' => 'products.scss.index',
            'rutaEditarVersion' => 'products.scss.version.edit',
            'rutaVerArchivo' => 'products.scss.file.show',
            'rutaEditarArchivo' => 'products.scss.file.edit',
            'rutaSubir' => 'products.scss.files.upload',
            'rutaCrearArchivo' => 'products.scss.file.create',
            // Los permisos son los mismos que exigen las rutas, no unos inventados: si se
            // pintara un botón con un permiso distinto, llevaría a un 403.
            'permisoVersion' => 'admin.scss.version.create',
            'permisoVersionEdit' => 'admin.scss.version.edit',
            'permisoSubir' => 'admin.scss.files.upload',
            'permisoArchivo' => 'admin.scss.file.create',
            'permisoVerArchivo' => 'admin.scss.file.show',
            'permisoEditarArchivo' => 'admin.scss.file.edit',
            'permisoBorrarArchivo' => 'admin.scss.file.destroy',
        ];
    }

    protected function archivosDeLaVersion()
    {
        return $this->scssVersion->files();
    }

    public function delete($fileId)
    {
        $this->authorize('admin.scss.file.destroy');

        // Acotado a esta versión en la propia consulta, no comparando después: si no es de
        // aquí, es un 404, que es lo que le corresponde a un recurso que para esta pantalla
        // no existe. Ver MGR-006.
        $file = ScssFile::query()
            ->where('scss_version_id', $this->scssVersion->id)
            ->findOrFail($fileId);

        ScssStorageService::deleteFile($this->product, $this->scssVersion, $file->filename);
        $file->delete();

        session()->flash('success', 'Archivo «' . $file->filename . '» borrado de la versión ' . $this->scssVersion->version . '.');
    }

    public function duplicateVersion()
    {
        $this->authorize('admin.scss.version.create');

        $nueva = $this->scssVersion->duplicate();

        session()->flash('success', "Versión duplicada. Nueva versión: {$nueva->version}");

        return redirect()->route('products.scss.version.show', [$this->product, $nueva]);
    }

    public function render()
    {
        return view('livewire.products.contenido.version-archivos', array_merge(
            $this->datosDeLaPantalla(),
            ['version' => $this->scssVersion]
        ))->layout('layouts.app');
    }
}
