<?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 Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Str;

class FileUpload extends Component
{
    use WithFileUploads;

    public Product $product;
    public ScssVersion $scssVersion;
    public $uploadedFiles = [];
    public $fileData = [];
    public $validationErrors = [];

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

        // 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.');
        }
    }

    public function updatedUploadedFiles()
    {
        $this->validationErrors = [];
        $this->processFiles();
    }

    public function processFiles()
    {
        $this->validationErrors = [];
        $newFileData = [];

        // Validar cantidad máxima
        if (count($this->uploadedFiles) > 10) {
            $this->validationErrors[] = 'Máximo 10 archivos permitidos por carga.';
            $this->uploadedFiles = array_slice($this->uploadedFiles, 0, 10);
        }

        foreach ($this->uploadedFiles as $index => $file) {
            try {
                // Validar formato
                $extension = strtolower($file->getClientOriginalExtension());
                if (!in_array($extension, ['scss', 'sass'])) {
                    $this->validationErrors[] = "El archivo '{$file->getClientOriginalName()}' no es válido. Solo se permiten archivos .scss y .sass.";
                    continue;
                }

                // Validar tamaño (2MB = 2048 KB)
                if ($file->getSize() > 2 * 1024 * 1024) {
                    $this->validationErrors[] = "El archivo '{$file->getClientOriginalName()}' excede el tamaño máximo de 2MB.";
                    continue;
                }

                // Extraer nombre sin extensión
                $originalName = $file->getClientOriginalName();
                $filename = pathinfo($originalName, PATHINFO_FILENAME);

                // Validar nombre del archivo (solo letras, números, guiones y guiones bajos)
                if (!preg_match('/^[a-zA-Z0-9_-]+$/', $filename)) {
                    $this->validationErrors[] = "El nombre del archivo '{$filename}' contiene caracteres no permitidos. Solo se permiten letras, números, guiones y guiones bajos.";
                    continue;
                }

                // Leer contenido
                $content = file_get_contents($file->getRealPath());

                // Verificar si es duplicado
                $existingFile = ScssFile::where('scss_version_id', $this->scssVersion->id)
                    ->where('filename', $filename)
                    ->first();

                $newFileData[] = [
                    'originalName' => $originalName,
                    'filename' => $filename,
                    'size' => $file->getSize(),
                    'content' => $content,
                    'isDuplicate' => $existingFile !== null,
                    'action' => $existingFile ? 'skip' : 'create',
                    'existingFileId' => $existingFile ? $existingFile->id : null,
                    'tempIndex' => $index,
                ];
            } catch (\Exception $e) {
                $this->validationErrors[] = "Error al procesar '{$file->getClientOriginalName()}' : " . $e->getMessage();
            }
        }

        $this->fileData = $newFileData;
    }

    public function setDuplicateAction($index, $action)
    {
        if (isset($this->fileData[$index])) {
            $this->fileData[$index]['action'] = $action;
        }
    }

    public function removeFile($index)
    {
        if (isset($this->fileData[$index])) {
            $tempIndex = $this->fileData[$index]['tempIndex'] ?? null;
            unset($this->fileData[$index]);
            $this->fileData = array_values($this->fileData);

            // También eliminar del array de uploadedFiles si existe
            if ($tempIndex !== null && isset($this->uploadedFiles[$tempIndex])) {
                unset($this->uploadedFiles[$tempIndex]);
                $this->uploadedFiles = array_values($this->uploadedFiles);
            }
        }
    }

    public function confirmUpload()
    {
        if (empty($this->fileData)) {
            session()->flash('error', 'No hay archivos para procesar.');
            return;
        }

        $savedCount = 0;
        $skippedCount = 0;
        $errors = [];

        foreach ($this->fileData as $file) {
            try {
                // Si la acción es 'skip', omitir
                if ($file['action'] === 'skip') {
                    $skippedCount++;
                    continue;
                }

                // Si es duplicado y acción es 'overwrite', eliminar el anterior
                if ($file['isDuplicate'] && $file['action'] === 'overwrite') {
                    $existingFile = ScssFile::find($file['existingFileId']);
                    if ($existingFile) {
                        // Eliminar archivo físico anterior
                        ScssStorageService::deleteFile(
                            $this->product,
                            $this->scssVersion,
                            $existingFile->filename
                        );
                        // Eliminar de BD
                        $existingFile->delete();
                    }
                }

                // Crear nuevo archivo en BD
                $scssFile = ScssFile::create([
                    'scss_version_id' => $this->scssVersion->id,
                    'filename' => $file['filename'],
                    'content' => $file['content'],
                    'created_by' => auth()->id(),
                ]);

                // Guardar archivo físico
                $saved = ScssStorageService::saveFile(
                    $this->product,
                    $this->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 procesar {$file['filename']}: " . $e->getMessage();
            }
        }

        // Preparar mensajes
        $messages = [];
        if ($savedCount > 0) {
            $messages[] = "Se crearon {$savedCount} archivo(s) correctamente.";
        }
        if ($skippedCount > 0) {
            $messages[] = "Se omitieron {$skippedCount} archivo(s).";
        }
        if (!empty($errors)) {
            $messages[] = "Errores: " . implode(' ', $errors);
        }

        if ($savedCount > 0) {
            session()->flash('success', implode(' ', $messages));
        } elseif (!empty($errors)) {
            session()->flash('error', implode(' ', $messages));
        }

        // Redirigir a la vista de versión
        return $this->redirect(route('products.scss.version.show', [$this->product, $this->scssVersion]), navigate: true);
    }

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

