<?php

namespace App\Livewire\Scss;

use App\Models\Products\Product;
use App\Models\Scss\ScssFile;
use App\Models\Scss\ScssVersion;
use App\Services\Scss\ScssStorageService;
use App\Livewire\Traits\HasFileValidation;
use Livewire\Component;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;

class Create extends Component
{
    use HasFileValidation;
    public Product $product;
    public ScssVersion $scssVersion;
    public string $version = '';
    public ?string $description = null;
    public array $files = [];
    public array $fileContents = []; // Contenido de cada archivo indexado por índice

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

        // Verificar que la versión pertenezca al producto
        if ($this->scssVersion->product_id !== $this->product->id) {
            abort(404, 'La versión SCSS no pertenece a este producto.');
        }

        $this->version = $this->scssVersion->version;
        $this->description = $this->scssVersion->description;

        // Inicializar con un archivo vacío
        if (empty($this->files)) {
            $this->addFile();
        }
    }

    public function addFile()
    {
        // Sincronizar fileContents con files antes de añadir uno nuevo
        foreach ($this->fileContents as $idx => $content) {
            if (isset($this->files[$idx])) {
                $this->files[$idx]['content'] = $content ?? '';
            }
        }
        
        $index = count($this->files);
        $this->files[] = [
            'filename' => '',
            'content' => '',
        ];
        $this->fileContents[] = '';
        $this->dispatch('fileAdded', $index);
    }

    public function removeFile($index)
    {
        if (isset($this->files[$index])) {
            $this->dispatch('fileRemoved', $index);
            unset($this->files[$index]);
            $this->files = array_values($this->files); // Reindexar array

            if (isset($this->fileContents[$index])) {
                unset($this->fileContents[$index]);
                $this->fileContents = array_values($this->fileContents); // Reindexar array
            }
        }

        // Si no quedan archivos, agregar uno vacío
        if (empty($this->files)) {
            $this->addFile();
        }
    }

    public function updatedFileContents($value, $index)
    {
        if (isset($this->files[$index])) {
            $this->files[$index]['content'] = $value;
        }
    }

    public function updatedFiles($value, $key)
    {
        // Asegurar que fileContents esté sincronizado
        $parts = explode('.', $key);
        if (count($parts) === 2 && $parts[1] === 'content') {
            $index = (int) $parts[0];
            if (isset($this->fileContents[$index])) {
                $this->fileContents[$index] = $value;
            }
        }
    }

    protected function getFileModel(): string
    {
        return ScssFile::class;
    }

    protected function getVersionId(): ?int
    {
        return $this->scssVersion->id ?? null;
    }

    protected function getVersionColumnName(): string
    {
        return 'scss_version_id';
    }

    protected function rules()
    {
        return $this->getFileValidationRules();
    }

    protected function messages()
    {
        return $this->getFileValidationMessages();
    }

    public function syncAndSave()
    {
        // Este método se llama desde el botón para sincronizar antes de guardar
        $this->dispatch('syncCodeMirror');
        
        // Dar tiempo para que se sincronice el contenido
        $this->dispatch('saveAfterSync');
    }

    public function save()
    {
        $this->authorize('admin.scss.file.create');
        
        // Sincronizar fileContents con files antes de validar
        foreach ($this->fileContents as $index => $content) {
            if (isset($this->files[$index])) {
                $this->files[$index]['content'] = $content ?? '';
            }
        }

        // Asegurar que todos los archivos tengan contenido (incluso si está vacío)
        foreach ($this->files as $index => &$file) {
            if (!isset($file['content']) || $file['content'] === null) {
                $file['content'] = $this->fileContents[$index] ?? '';
            }
        }
        unset($file); // Liberar referencia

        // Validar
        try {
            $validated = $this->validate();
        } catch (\Illuminate\Validation\ValidationException $e) {
            // Los errores de validación se mostrarán automáticamente
            return;
        }

        // Usar la versión existente (siempre debe existir)
        $scssVersion = $this->scssVersion;

        $savedCount = 0;
        $errors = [];

        foreach ($this->files as $index => $file) {
            try {
                // Guardar en base de datos
                $scssFile = ScssFile::create([
                    'scss_version_id' => $scssVersion->id,
                    'filename' => $file['filename'],
                    'content' => $file['content'],
                    'created_by' => auth()->id(),
                ]);

                // Guardar físicamente en storage
                $saved = ScssStorageService::saveFile(
                    $this->product,
                    $scssVersion,
                    $file['filename'],
                    $file['content']
                );

                if (!$saved) {
                    // Si falla el guardado físico, eliminar de BD
                    $scssFile->delete();
                    $errors[] = "Error al guardar el archivo físico: {$file['filename']}";
                } else {
                    $savedCount++;
                }
            } catch (\Exception $e) {
                $errors[] = "Error al guardar {$file['filename']}: " . $e->getMessage();
            }
        }

        // Si no se guardó ningún archivo y es una versión nueva, eliminar la versión
        if ($savedCount === 0 && !$this->scssVersion) {
            $scssVersion->delete();
            session()->flash('error', 'No se pudo guardar ningún archivo. La versión no se creó.');
            return;
        }

        if ($savedCount > 0) {
            $message = $this->scssVersion
                ? "Se agregaron {$savedCount} archivo(s) SCSS correctamente."
                : "Se guardaron {$savedCount} archivo(s) SCSS correctamente.";
            session()->flash('success', $message);
            
            // Redirigir a la versión solo si se guardó al menos un archivo
            return $this->redirect(route('products.scss.version.show', [$this->product, $scssVersion]), navigate: true);
        }

        if (!empty($errors)) {
            session()->flash('error', implode('<br>', $errors));
        } else {
            // Si no se guardó nada y no hay errores específicos, mostrar error genérico
            session()->flash('error', 'No se pudo guardar ningún archivo. Por favor, verifica que todos los campos estén completos.');
        }
    }

    public function render()
    {
        return view('livewire.scss.create', [
            'product' => $this->product,
            'scssVersion' => $this->scssVersion,
        ])->layout('layouts.clean');
    }
}
