<?php

namespace App\Livewire\Traits;

trait HasFileValidation
{
    /**
     * Obtiene el modelo de archivo a usar para validar duplicados (ej: ScssFile::class)
     */
    abstract protected function getFileModel(): string;

    /**
     * Obtiene el ID de la versión para validar duplicados
     */
    abstract protected function getVersionId(): ?int;

    /**
     * Obtiene las reglas de validación base para archivos
     */
    protected function getFileValidationRules(): array
    {
        $rules = [];

        // Reglas para archivos (siempre requeridas)
        $rules['files'] = [
            'required',
            'array',
            'min:1',
        ];
        
        $rules['files.*.filename'] = [
            'required',
            'string',
            'max:255',
            function ($attribute, $value, $fail) {
                // Validar que el nombre del archivo no tenga caracteres especiales
                if (!preg_match('/^[a-zA-Z0-9_-]+$/', $value)) {
                    $fail('El nombre del archivo solo puede contener letras, números, guiones y guiones bajos.');
                }
            },
        ];
        
        $rules['files.*.content'] = [
            'required',
            'string',
        ];

        // Validar que no existan duplicados (mismo nombre dentro de la versión)
        $rules['files.*.filename'][] = function ($attribute, $value, $fail) {
            // Extraer el índice correctamente: "files.1.filename" -> 1
            $parts = explode('.', $attribute);
            $index = isset($parts[1]) && is_numeric($parts[1]) ? (int) $parts[1] : -1;

            if ($value && $index >= 0) {
                // Verificar duplicados dentro del mismo formulario
                foreach ($this->files as $i => $file) {
                    if ($i !== $index && isset($file['filename']) && !empty($file['filename']) && $file['filename'] === $value) {
                        $fail('Ya existe otro archivo con el mismo nombre en este formulario.');
                        return;
                    }
                }

                // Verificar duplicados en la BD si hay una versión existente
                $versionId = $this->getVersionId();
                if ($versionId) {
                    $fileModel = $this->getFileModel();
                    $versionColumn = $this->getVersionColumnName();
                    
                    $exists = $fileModel::where($versionColumn, $versionId)
                        ->where('filename', $value)
                        ->exists();
                    if ($exists) {
                        $fail('Ya existe un archivo con este nombre en esta versión.');
                    }
                }
            }
        };

        return $rules;
    }

    /**
     * Obtiene el nombre de la columna de versión (ej: 'scss_version_id', 'js_version_id')
     */
    abstract protected function getVersionColumnName(): string;

    /**
     * Obtiene los mensajes de validación para archivos
     */
    protected function getFileValidationMessages(): array
    {
        return [
            'files.required' => 'Debe agregar al menos un archivo.',
            'files.min' => 'Debe agregar al menos un archivo.',
            'files.*.filename.required' => 'El nombre del archivo es obligatorio.',
            'files.*.filename.max' => 'El nombre del archivo no puede exceder 255 caracteres.',
            'files.*.content.required' => 'El contenido del archivo es obligatorio.',
        ];
    }
}

