<?php
/**
 * CierreCaja - Procesar XMLs de facturas emitidas
 * Parsea XML FEL Guatemala, extrae datos clave y guarda en BD
 */

header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../config/db.php';

// Mapeo fijo de códigos de establecimiento
const SUCURSALES = [
    1 => 'SUFARMA ZONA 0',
    2 => 'SUFARMA ZONA 1',
    3 => 'SUFARMA CENTRO SANFE',
    4 => 'SUFARMA SECTOR 8',
];

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'error' => 'Método no permitido']);
    exit;
}

if (empty($_FILES['xmlFiles'])) {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'No se recibieron archivos XML']);
    exit;
}

$pdo = getConnection();

// Ensure table exists
try {
    $sqlMigration = file_get_contents(__DIR__ . '/../sql/migration.sql');
    $pdo->exec($sqlMigration);
} catch (PDOException $e) {
    // Table likely already exists, continue
}

$files = $_FILES['xmlFiles'];
$totalArchivos = is_array($files['name']) ? count($files['name']) : 1;
$insertados = 0;
$duplicados = 0;
$errores = [];
$detalle = [];

$stmt = $pdo->prepare("
    INSERT IGNORE INTO cierre_caja_facturas 
    (codigo_establecimiento, sucursal_nombre, fecha_emision, gran_total, 
     nit_emisor, nombre_emisor, numero_autorizacion, serie, nombre_receptor)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
");

for ($i = 0; $i < $totalArchivos; $i++) {
    $name = is_array($files['name']) ? $files['name'][$i] : $files['name'];
    $tmpName = is_array($files['tmp_name']) ? $files['tmp_name'][$i] : $files['tmp_name'];
    $error = is_array($files['error']) ? $files['error'][$i] : $files['error'];

    if ($error !== UPLOAD_ERR_OK) {
        $errores[] = "$name: Error de subida ($error)";
        continue;
    }

    $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    if ($ext !== 'xml') {
        $errores[] = "$name: No es un archivo XML";
        continue;
    }

    try {
        $xmlContent = file_get_contents($tmpName);
        $data = parsearXMLFEL($xmlContent);

        if (!$data) {
            $errores[] = "$name: No se pudo parsear el XML";
            continue;
        }

        $stmt->execute([
            $data['codigo_establecimiento'],
            $data['sucursal_nombre'],
            $data['fecha_emision'],
            $data['gran_total'],
            $data['nit_emisor'],
            $data['nombre_emisor'],
            $data['numero_autorizacion'],
            $data['serie'],
            $data['nombre_receptor'],
        ]);

        if ($stmt->rowCount() > 0) {
            $insertados++;
            $detalle[] = [
                'archivo' => $name,
                'sucursal' => $data['sucursal_nombre'],
                'fecha' => $data['fecha_emision'],
                'total' => $data['gran_total'],
                'estado' => 'insertado'
            ];
        } else {
            $duplicados++;
            $detalle[] = [
                'archivo' => $name,
                'sucursal' => $data['sucursal_nombre'],
                'fecha' => $data['fecha_emision'],
                'total' => $data['gran_total'],
                'estado' => 'duplicado'
            ];
        }
    } catch (Exception $e) {
        $errores[] = "$name: " . $e->getMessage();
    }
}

echo json_encode([
    'success' => true,
    'resumen' => [
        'total_archivos' => $totalArchivos,
        'insertados' => $insertados,
        'duplicados' => $duplicados,
        'errores' => count($errores),
    ],
    'detalle' => $detalle,
    'errores' => $errores,
]);

/**
 * Parsea un XML FEL de Guatemala y extrae los datos necesarios
 */
function parsearXMLFEL(string $xmlContent): ?array
{
    // Suppress warnings for malformed XML
    libxml_use_internal_errors(true);
    $xml = new DOMDocument();
    if (!$xml->loadXML($xmlContent)) {
        return null;
    }
    libxml_clear_errors();

    // Namespaces comunes de FEL Guatemala
    $namespaces = [
        'dte' => 'http://www.sat.gob.gt/dte/fel/0.2.0',
        'dte1' => 'http://www.sat.gob.gt/dte/fel/0.1.0',
    ];

    // Registrar namespaces for XPath
    $xpath = new DOMXPath($xml);
    foreach ($namespaces as $prefix => $ns) {
        $xpath->registerNamespace($prefix, $ns);
    }

    /**
     * Busca un elemento o atributo usando XPath con soporte para múltiples namespaces
     */
    $queryValue = function (string $expression) use ($xpath) {
        $nodes = $xpath->query($expression);
        if ($nodes && $nodes->length > 0) {
            return trim($nodes->item(0)->nodeValue);
        }
        return null;
    };

    $queryAttr = function (string $expression, string $attrName) use ($xpath) {
        $nodes = $xpath->query($expression);
        if ($nodes && $nodes->length > 0) {
            $el = $nodes->item(0);
            if ($el instanceof DOMElement) {
                return trim($el->getAttribute($attrName));
            }
        }
        return null;
    };

    // ── Emisor ──
    // Intentar con diferentes namespaces para la etiqueta Emisor
    $codigoEstablecimiento = (int) ($queryAttr('//dte:Emisor', 'CodigoEstablecimiento') 
                                 ?? $queryAttr('//dte1:Emisor', 'CodigoEstablecimiento') 
                                 ?? $queryAttr('//*[local-name()="Emisor"]', 'CodigoEstablecimiento') 
                                 ?? 0);

    $nitEmisor = $queryAttr('//dte:Emisor', 'NITEmisor') ?? $queryAttr('//dte1:Emisor', 'NITEmisor') ?? '';
    $nombreEmisor = $queryAttr('//dte:Emisor', 'NombreComercial') ?? $queryAttr('//dte:Emisor', 'NombreEmisor') ?? '';

    // Mapear código a nombre de sucursal
    $sucursalNombre = SUCURSALES[$codigoEstablecimiento] ?? "SUCURSAL DESCONOCIDA ($codigoEstablecimiento)";

    // ── Fecha ──
    $fechaHora = $queryAttr('//dte:DatosGenerales', 'FechaHoraEmision') 
              ?? $queryAttr('//dte1:DatosGenerales', 'FechaHoraEmision')
              ?? $queryAttr('//*[local-name()="DatosGenerales"]', 'FechaHoraEmision')
              ?? '';
    
    $fechaEmision = '';
    if ($fechaHora) {
        $fechaEmision = substr($fechaHora, 0, 10); // YYYY-MM-DD
    }

    // ── GranTotal ──
    $granTotal = (float) ($queryValue('//dte:GranTotal') 
                       ?? $queryValue('//dte1:GranTotal') 
                       ?? $queryValue('//*[local-name()="GranTotal"]') 
                       ?? 0.0);

    // ── Receptor ──
    $nombreReceptor = $queryAttr('//dte:Receptor', 'NombreReceptor') ?? '';

    // ── Numero Autorización (UUID) ──
    $numAutorizacion = $queryValue('//dte:NumeroAutorizacion') 
                    ?? $queryValue('//dte1:NumeroAutorizacion')
                    ?? $queryValue('//*[local-name()="NumeroAutorizacion"]')
                    ?? '';
    
    $serie = $queryAttr('//dte:NumeroAutorizacion', 'Serie') ?? '';

    if (empty($fechaEmision) || $granTotal <= 0) {
        return null;
    }

    return [
        'codigo_establecimiento' => $codigoEstablecimiento,
        'sucursal_nombre' => $sucursalNombre,
        'fecha_emision' => $fechaEmision,
        'gran_total' => $granTotal,
        'nit_emisor' => $nitEmisor,
        'nombre_emisor' => $nombreEmisor,
        'numero_autorizacion' => $numAutorizacion,
        'serie' => $serie,
        'nombre_receptor' => $nombreReceptor,
    ];
}
