<?php

namespace App\Utils;

/**
 * Validador de archivos CSV antes del procesamiento
 */
class CSVPreValidator
{
    private $max_file_size = 5242880; // 5MB
    private $allowed_encodings = ['UTF-8', 'ISO-8859-1', 'Windows-1252'];

    public function validateFile($file_path, $expected_header)
    {
        $errors = [];

        // Verificar tamaño del archivo
        if (filesize($file_path) > $this->max_file_size) {
            $errors[] = "El archivo es demasiado grande. Tamaño máximo permitido: 5MB";
        }

        // Verificar si el archivo es legible
        if (!is_readable($file_path)) {
            $errors[] = "No se puede leer el archivo. Verifica los permisos.";
            return $errors;
        }

        // Abrir archivo y validar estructura básica
        $handle = fopen($file_path, 'r');
        if (!$handle) {
            $errors[] = "No se pudo abrir el archivo CSV.";
            return $errors;
        }

        // Detectar encoding
        $first_line = fgets($handle);
        rewind($handle);

        $encoding = mb_detect_encoding($first_line, $this->allowed_encodings, true);
        if (!$encoding) {
            $errors[] = "Codificación de archivo no soportada. Use UTF-8, ISO-8859-1 o Windows-1252.";
        }

        // Validar encabezado
        $header = fgetcsv($handle, 2000, ",");
        if (!$header) {
            $errors[] = "No se pudo leer el encabezado del archivo.";
            fclose($handle);
            return $errors;
        }

        $header = array_map('trim', $header);

        if ($header !== $expected_header) {
            $errors[] = $this->generateHeaderComparisonError($header, $expected_header);
        }

        // Validar que hay al menos una fila de datos
        $row_count = 0;
        $empty_rows = 0;
        $inconsistent_columns = 0;

        while (($data = fgetcsv($handle, 2000, ",")) !== FALSE) {
            $row_count++;

            // Contar filas vacías
            if (empty(array_filter($data))) {
                $empty_rows++;
                continue;
            }

            // Verificar consistencia en número de columnas
            if (count($data) !== count($expected_header)) {
                $inconsistent_columns++;
            }

            // Solo verificar las primeras 1000 filas para performance
            if ($row_count > 1000) break;
        }

        fclose($handle);

        if ($row_count === 0) {
            $errors[] = "El archivo no contiene datos (solo encabezado).";
        }

        if ($inconsistent_columns > 0) {
            $errors[] = "Se encontraron {$inconsistent_columns} filas con número inconsistente de columnas.";
        }

        // Generar advertencias
        $warnings = [];
        if ($empty_rows > 0) {
            $warnings[] = "Se encontraron {$empty_rows} filas vacías que serán ignoradas.";
        }

        return [
            'errors' => $errors,
            'warnings' => $warnings,
            'stats' => [
                'total_rows' => $row_count,
                'empty_rows' => $empty_rows,
                'inconsistent_columns' => $inconsistent_columns,
                'encoding' => $encoding
            ]
        ];
    }

    private function generateHeaderComparisonError($actual, $expected)
    {
        $missing = array_diff($expected, $actual);
        $extra = array_diff($actual, $expected);

        $message = "Encabezado del CSV incorrecto:\n";

        if (!empty($missing)) {
            $message .= "Columnas faltantes: " . implode(', ', $missing) . "\n";
        }

        if (!empty($extra)) {
            $message .= "Columnas extra: " . implode(', ', $extra) . "\n";
        }

        $message .= "\nEncabezado esperado: " . implode(', ', $expected);
        $message .= "\nEncabezado encontrado: " . implode(', ', $actual);

        return $message;
    }
}
