<?php

namespace App\Livewire\ScssCdn;

use App\Models\Products\Product;
use App\Models\ScssCdn\ScssCdnBundle;
use App\Models\ScssCdn\ScssCdnFile;
use App\Services\ScssCdn\ScssCdnImportParser;
use App\Services\ScssCdn\ScssCdnStorageService;
use App\Services\ScssCdn\ScssCdnUrlService;
use App\Support\RevisionDeCodigo;
use Livewire\Component;

class FileEdit extends Component
{
    public Product $product;
    public ScssCdnBundle $bundle;
    public ScssCdnFile $file;
    public string $content = '';
    public ?string $scssValidationError = null;
    public bool $scssValid = true;

    /**
     * Lo que ha encontrado la revisión del archivo.
     *
     * Ver {@see \App\Support\RevisionDeCodigo}.
     *
     * @var array<int, array{tipo: string, mensaje: string, linea: ?int}>
     */
    public array $revision = [];

    public function mount(Product $product, ScssCdnBundle $bundle, ScssCdnFile $file)
    {
        $this->product = $product;
        $this->bundle = $bundle->load('product');
        $this->file = $file->load(['bundle', 'creator', 'updater']);

        // Verificar que el archivo pertenezca al bundle y el bundle al producto
        if ($this->file->scss_cdn_bundle_id !== $this->bundle->id) {
            abort(404, 'El archivo no pertenece a este bundle.');
        }
        if ($this->bundle->product_id !== $this->product->id) {
            abort(404, 'El bundle no pertenece a este producto.');
        }

        // Leer contenido desde storage
        $this->content = ScssCdnStorageService::getFile(
            $this->product,
            $this->bundle,
            $this->file->relative_path
        ) ?? '';
    }

    /**
     * Revisa el archivo y deja el resultado en $revision.
     *
     * **Antes solo miraba si estaba vacío** y la pantalla pintaba «✓ SCSS válido»: un
     * archivo con una llave sin cerrar pasaba con el visto bueno. Los `@import` no se
     * comprueban aquí —en un bundle los archivos viven en carpetas y de eso ya se ocupa
     * `ScssCdnImportParser`, que sabe resolver rutas—.
     */
    public function validateScss()
    {
        $this->scssValidationError = null;
        $this->scssValid = true;
        $this->revision = [];

        if (empty(trim($this->content))) {
            $this->scssValidationError = 'El archivo está vacío.';
            $this->scssValid = false;
            $this->revision = [[
                'tipo' => 'error',
                'mensaje' => 'El archivo está vacío: no hay nada que servirle al cliente.',
                'linea' => null,
            ]];

            return;
        }

        $this->revision = RevisionDeCodigo::revisar($this->content, RevisionDeCodigo::SCSS);
        $this->scssValid = ! RevisionDeCodigo::hayErrores($this->revision);

        if (! $this->scssValid) {
            $this->scssValidationError = 'El archivo tiene errores que impiden guardarlo.';
        }
    }

    public function save()
    {
        // Ver known-issues MGR-005: el gate de la ruta no basta como única defensa.
        $this->authorize('admin.scss-cdn.file.edit');

        // Validar SCSS antes de guardar
        $this->validateScss();

        if (!$this->scssValid) {
            $this->addError('content', $this->scssValidationError ?? 'SCSS inválido');
            return;
        }

        try {
            // Actualizar en BD (solo updated_by)
            $this->file->update([
                'updated_by' => auth()->id(),
            ]);

            // Actualizar archivo físico en storage
            $saved = ScssCdnStorageService::saveFile(
                $this->product,
                $this->bundle,
                $this->file->relative_path,
                $this->content
            );

            if (!$saved) {
                $this->addError('content', 'Error al guardar el archivo físico.');
                return;
            }

            session()->flash('success', 'Archivo SCSS actualizado correctamente.');

            return $this->redirect(route('products.scss-cdn.bundle.show', [$this->product, $this->bundle]), navigate: true);
        } catch (\Exception $e) {
            $this->addError('content', 'Error al guardar: ' . $e->getMessage());
        }
    }

    public function getFileUrl()
    {
        return ScssCdnUrlService::getFileUrl($this->file);
    }

    public function render()
    {
        return view('livewire.scss-cdn.file-edit', [
            'product' => $this->product,
            'fileUrl' => $this->getFileUrl(),
        ])->layout('layouts.clean');
    }
}
