<?php
/**
 * Test script para API de Datos de Campo
 * Sistema de Inventario Forestal de Guatemala V1.0
 * 
 * Este script prueba todos los endpoints de la API de datos de campo
 * incluyendo sincronización masiva, validaciones y manejo de errores.
 */

// Configuración de la API
$API_BASE_URL = 'http://localhost/api';
$TEST_EMAIL = 'admin@test.com';
$TEST_PASSWORD = 'admin123';

// Variables globales para las pruebas
$authToken = null;
$testProjectId = null;
$testRodalId = null;
$testFieldDataIds = [];

/**
 * Función para hacer peticiones HTTP
 */
function makeRequest($url, $method = 'GET', $data = null, $token = null) {
    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        $token ? "Authorization: Bearer $token" : ''
    ]);
    
    if ($data) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    }
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    return [
        'code' => $httpCode,
        'body' => json_decode($response, true)
    ];
}

/**
 * Función para mostrar resultados de pruebas
 */
function showTestResult($testName, $expected, $actual, $details = '') {
    $status = ($expected === $actual) ? '✅ PASS' : '❌ FAIL';
    echo "\n$status - $testName";
    if ($expected !== $actual) {
        echo "\n  Esperado: $expected, Obtenido: $actual";
    }
    if ($details) {
        echo "\n  Detalles: $details";
    }
    echo "\n";
}

/**
 * Función para mostrar respuesta de API
 */
function showApiResponse($title, $response) {
    echo "\n=== $title ===\n";
    echo "HTTP Code: " . $response['code'] . "\n";
    echo "Response: " . json_encode($response['body'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
}

echo "🌲 INICIANDO PRUEBAS DE API - DATOS DE CAMPO 🌲\n";
echo "================================================\n";

// 1. AUTENTICACIÓN
echo "\n1. PRUEBAS DE AUTENTICACIÓN\n";
echo "----------------------------\n";

$loginResponse = makeRequest("$API_BASE_URL/auth/login", 'POST', [
    'email' => $TEST_EMAIL,
    'password' => $TEST_PASSWORD
]);

showApiResponse("Login de Usuario", $loginResponse);

if ($loginResponse['code'] === 200 && isset($loginResponse['body']['data']['token'])) {
    $authToken = $loginResponse['body']['data']['token'];
    showTestResult("Login exitoso", 200, $loginResponse['code']);
} else {
    echo "❌ ERROR: No se pudo autenticar. Terminando pruebas.\n";
    exit(1);
}

// 2. PREPARAR DATOS DE PRUEBA
echo "\n2. PREPARACIÓN DE DATOS DE PRUEBA\n";
echo "----------------------------------\n";

// Crear proyecto de prueba
$projectData = [
    'nombre_proyecto' => 'Proyecto Test Field Data ' . date('Y-m-d H:i:s'),
    'nombre_finca' => 'Finca Test',
    'departamento' => 'Guatemala',
    'municipio' => 'Guatemala',
    'aldea' => 'Test',
    'nombre_propietario' => 'Propietario Test',
    'nombre_regente_forestal' => 'Regente Test'
];

$projectResponse = makeRequest("$API_BASE_URL/projects", 'POST', $projectData, $authToken);
showApiResponse("Crear Proyecto de Prueba", $projectResponse);

if ($projectResponse['code'] === 201) {
    $testProjectId = $projectResponse['body']['data']['id'];
    showTestResult("Proyecto creado", 201, $projectResponse['code']);
} else {
    echo "❌ ERROR: No se pudo crear proyecto de prueba.\n";
    exit(1);
}

// Crear rodal de prueba
$rodalData = [
    'nombre_rodal' => 'Rodal Test Field Data',
    'area_ha' => 10.5
];

$rodalResponse = makeRequest("$API_BASE_URL/projects/$testProjectId/rodales", 'POST', $rodalData, $authToken);
showApiResponse("Crear Rodal de Prueba", $rodalResponse);

if ($rodalResponse['code'] === 201) {
    $testRodalId = $rodalResponse['body']['data']['id'];
    showTestResult("Rodal creado", 201, $rodalResponse['code']);
} else {
    echo "❌ ERROR: No se pudo crear rodal de prueba.\n";
    exit(1);
}

// 3. PRUEBAS DE SINCRONIZACIÓN MASIVA
echo "\n3. PRUEBAS DE SINCRONIZACIÓN MASIVA\n";
echo "------------------------------------\n";

// Datos de prueba para sincronización
$syncData = [
    'records' => [
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 1,
            'latitud' => 14.6349,
            'longitud' => -90.5069,
            'especie_id' => 1, // Pinus maximinoi
            'dap_cm' => 25.5,
            'altura_m' => 12.3,
            'condicion_arbol' => 'Sano',
            'fecha_captura' => date('Y-m-d H:i:s')
        ],
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 1,
            'latitud' => 14.6350,
            'longitud' => -90.5070,
            'especie_id' => 2, // Cupressus lusitanica
            'dap_cm' => 18.2,
            'altura_m' => 8.7,
            'condicion_arbol' => 'Bifurcado',
            'fecha_captura' => date('Y-m-d H:i:s')
        ],
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 2,
            'latitud' => 14.6351,
            'longitud' => -90.5071,
            'especie_id' => 1,
            'dap_cm' => 220.0, // Valor atípico para probar alertas
            'altura_m' => 15.5,
            'condicion_arbol' => 'Sano',
            'fecha_captura' => date('Y-m-d H:i:s')
        ]
    ]
];

$syncResponse = makeRequest("$API_BASE_URL/field-data/sync", 'POST', $syncData, $authToken);
showApiResponse("Sincronización Masiva", $syncResponse);

if ($syncResponse['code'] === 201) {
    showTestResult("Sincronización exitosa", 201, $syncResponse['code']);
    if (isset($syncResponse['body']['data']['inserted_ids'])) {
        $testFieldDataIds = $syncResponse['body']['data']['inserted_ids'];
        echo "IDs insertados: " . implode(', ', $testFieldDataIds) . "\n";
    }
} else {
    showTestResult("Sincronización falló", 201, $syncResponse['code']);
}

// 4. PRUEBAS DE VALIDACIÓN
echo "\n4. PRUEBAS DE VALIDACIÓN\n";
echo "------------------------\n";

// Datos inválidos - DAP negativo
$invalidData = [
    'records' => [
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 3,
            'latitud' => 14.6352,
            'longitud' => -90.5072,
            'especie_id' => 1,
            'dap_cm' => -5.0, // Valor inválido
            'altura_m' => 10.0,
            'condicion_arbol' => 'Sano'
        ]
    ]
];

$invalidResponse = makeRequest("$API_BASE_URL/field-data/sync", 'POST', $invalidData, $authToken);
showApiResponse("Validación - DAP Negativo", $invalidResponse);
showTestResult("Validación rechaza DAP negativo", 400, $invalidResponse['code']);

// Datos inválidos - Coordenadas fuera de Guatemala
$invalidGpsData = [
    'records' => [
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 4,
            'latitud' => 40.7128, // Nueva York
            'longitud' => -74.0060,
            'especie_id' => 1,
            'dap_cm' => 25.0,
            'altura_m' => 10.0,
            'condicion_arbol' => 'Sano'
        ]
    ]
];

$invalidGpsResponse = makeRequest("$API_BASE_URL/field-data/sync", 'POST', $invalidGpsData, $authToken);
showApiResponse("Validación - GPS Fuera de Guatemala", $invalidGpsResponse);
showTestResult("Validación rechaza GPS fuera de Guatemala", 400, $invalidGpsResponse['code']);

// Datos inválidos - Especie inexistente
$invalidSpeciesData = [
    'records' => [
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 5,
            'latitud' => 14.6353,
            'longitud' => -90.5073,
            'especie_id' => 9999, // Especie inexistente
            'dap_cm' => 25.0,
            'altura_m' => 10.0,
            'condicion_arbol' => 'Sano'
        ]
    ]
];

$invalidSpeciesResponse = makeRequest("$API_BASE_URL/field-data/sync", 'POST', $invalidSpeciesData, $authToken);
showApiResponse("Validación - Especie Inexistente", $invalidSpeciesResponse);
showTestResult("Validación rechaza especie inexistente", 400, $invalidSpeciesResponse['code']);

// 5. PRUEBAS DE CONSULTA DE DATOS
echo "\n5. PRUEBAS DE CONSULTA DE DATOS\n";
echo "-------------------------------\n";

// Obtener datos por rodal
$rodalDataResponse = makeRequest("$API_BASE_URL/rodales/$testRodalId/field-data", 'GET', null, $authToken);
showApiResponse("Obtener Datos por Rodal", $rodalDataResponse);
showTestResult("Consulta por rodal exitosa", 200, $rodalDataResponse['code']);

if ($rodalDataResponse['code'] === 200) {
    $recordCount = count($rodalDataResponse['body']['data']['records']);
    echo "Registros encontrados: $recordCount\n";
    
    // Verificar estadísticas
    if (isset($rodalDataResponse['body']['data']['statistics'])) {
        $stats = $rodalDataResponse['body']['data']['statistics'];
        echo "Estadísticas:\n";
        echo "  - Total registros: " . $stats['total_registros'] . "\n";
        echo "  - DAP promedio: " . $stats['dap_promedio'] . " cm\n";
        echo "  - Altura promedio: " . $stats['altura_promedio'] . " m\n";
        echo "  - DAP outliers: " . $stats['dap_outliers'] . "\n";
        echo "  - Altura outliers: " . $stats['altura_outliers'] . "\n";
    }
}

// Obtener registro específico (si hay IDs disponibles)
if (!empty($testFieldDataIds)) {
    $firstId = $testFieldDataIds[0];
    $recordResponse = makeRequest("$API_BASE_URL/field-data/$firstId", 'GET', null, $authToken);
    showApiResponse("Obtener Registro Específico", $recordResponse);
    showTestResult("Consulta registro específico", 200, $recordResponse['code']);
    
    // Verificar alertas de valores atípicos
    if ($recordResponse['code'] === 200 && isset($recordResponse['body']['data']['alerts'])) {
        $alerts = $recordResponse['body']['data']['alerts'];
        echo "Alertas encontradas: " . count($alerts) . "\n";
        foreach ($alerts as $alert) {
            echo "  - " . $alert['type'] . ": " . $alert['message'] . "\n";
        }
    }
}

// 6. PRUEBAS DE REGISTROS PENDIENTES
echo "\n6. PRUEBAS DE REGISTROS PENDIENTES\n";
echo "----------------------------------\n";

// Crear registros pendientes de sincronización
$pendingData = [
    'records' => [
        [
            'rodal_id' => $testRodalId,
            'numero_parcela' => 10,
            'latitud' => 14.6360,
            'longitud' => -90.5080,
            'especie_id' => 3,
            'dap_cm' => 30.0,
            'altura_m' => 14.0,
            'condicion_arbol' => 'Sano',
            'estado_sincronizacion' => 'Pendiente' // Explícitamente pendiente
        ]
    ]
];

// Usar el modelo directamente para crear registros pendientes
// (En una implementación real, esto vendría de la app móvil offline)

// Obtener registros pendientes
$pendingResponse = makeRequest("$API_BASE_URL/field-data/pending-sync", 'GET', null, $authToken);
showApiResponse("Obtener Registros Pendientes", $pendingResponse);
showTestResult("Consulta registros pendientes", 200, $pendingResponse['code']);

// 7. PRUEBAS DE ACTUALIZACIÓN
echo "\n7. PRUEBAS DE ACTUALIZACIÓN\n";
echo "---------------------------\n";

if (!empty($testFieldDataIds)) {
    $updateId = $testFieldDataIds[0];
    $updateData = [
        'dap_cm' => 26.0,
        'altura_m' => 13.0,
        'condicion_arbol' => 'Bifurcado'
    ];
    
    $updateResponse = makeRequest("$API_BASE_URL/field-data/$updateId", 'PUT', $updateData, $authToken);
    showApiResponse("Actualizar Registro", $updateResponse);
    showTestResult("Actualización exitosa", 200, $updateResponse['code']);
}

// 8. PRUEBAS DE MARCAR COMO SINCRONIZADO
echo "\n8. PRUEBAS DE MARCAR COMO SINCRONIZADO\n";
echo "--------------------------------------\n";

if (!empty($testFieldDataIds)) {
    $markSyncedData = [
        'ids' => [$testFieldDataIds[0]]
    ];
    
    $markSyncedResponse = makeRequest("$API_BASE_URL/field-data/mark-synced", 'PUT', $markSyncedData, $authToken);
    showApiResponse("Marcar como Sincronizado", $markSyncedResponse);
    showTestResult("Marcar como sincronizado", 200, $markSyncedResponse['code']);
}

// 9. PRUEBAS DE LÍMITES Y PAGINACIÓN
echo "\n9. PRUEBAS DE LÍMITES Y PAGINACIÓN\n";
echo "----------------------------------\n";

// Probar límite de lote muy grande
$largeBatchData = [
    'records' => []
];

// Crear 101 registros (excede el límite de 100)
for ($i = 1; $i <= 101; $i++) {
    $largeBatchData['records'][] = [
        'rodal_id' => $testRodalId,
        'numero_parcela' => $i,
        'latitud' => 14.6349 + ($i * 0.0001),
        'longitud' => -90.5069 + ($i * 0.0001),
        'especie_id' => 1,
        'dap_cm' => 20.0 + $i,
        'altura_m' => 10.0 + $i,
        'condicion_arbol' => 'Sano'
    ];
}

$largeBatchResponse = makeRequest("$API_BASE_URL/field-data/sync", 'POST', $largeBatchData, $authToken);
showApiResponse("Lote Muy Grande (101 registros)", $largeBatchResponse);
showTestResult("Rechaza lote muy grande", 400, $largeBatchResponse['code']);

// Probar paginación
$paginationResponse = makeRequest("$API_BASE_URL/rodales/$testRodalId/field-data?limit=2&offset=0", 'GET', null, $authToken);
showApiResponse("Paginación (limit=2, offset=0)", $paginationResponse);
showTestResult("Paginación funciona", 200, $paginationResponse['code']);

if ($paginationResponse['code'] === 200) {
    $pagination = $paginationResponse['body']['data']['pagination'];
    echo "Paginación:\n";
    echo "  - Total: " . $pagination['total'] . "\n";
    echo "  - Límite: " . $pagination['limit'] . "\n";
    echo "  - Offset: " . $pagination['offset'] . "\n";
    echo "  - Devueltos: " . $pagination['returned'] . "\n";
}

// 10. PRUEBAS DE PERMISOS
echo "\n10. PRUEBAS DE PERMISOS\n";
echo "-----------------------\n";

// Intentar acceder a rodal inexistente
$invalidRodalResponse = makeRequest("$API_BASE_URL/rodales/99999/field-data", 'GET', null, $authToken);
showApiResponse("Acceso a Rodal Inexistente", $invalidRodalResponse);
showTestResult("Rechaza rodal inexistente", 403, $invalidRodalResponse['code']);

// 11. PRUEBAS DE MANEJO DE ERRORES
echo "\n11. PRUEBAS DE MANEJO DE ERRORES\n";
echo "--------------------------------\n";

// Request sin token de autenticación
$noAuthResponse = makeRequest("$API_BASE_URL/field-data/pending-sync", 'GET');
showApiResponse("Sin Autenticación", $noAuthResponse);
showTestResult("Rechaza sin autenticación", 401, $noAuthResponse['code']);

// Request con datos malformados
$malformedResponse = makeRequest("$API_BASE_URL/field-data/sync", 'POST', ['invalid' => 'data'], $authToken);
showApiResponse("Datos Malformados", $malformedResponse);
showTestResult("Rechaza datos malformados", 400, $malformedResponse['code']);

// 12. LIMPIEZA DE DATOS DE PRUEBA
echo "\n12. LIMPIEZA DE DATOS DE PRUEBA\n";
echo "-------------------------------\n";

// Eliminar registros de campo creados
if (!empty($testFieldDataIds)) {
    foreach ($testFieldDataIds as $id) {
        $deleteResponse = makeRequest("$API_BASE_URL/field-data/$id", 'DELETE', null, $authToken);
        if ($deleteResponse['code'] === 200) {
            echo "✅ Registro $id eliminado\n";
        } else {
            echo "❌ Error eliminando registro $id\n";
        }
    }
}

// Eliminar rodal de prueba
if ($testRodalId) {
    $deleteRodalResponse = makeRequest("$API_BASE_URL/rodales/$testRodalId", 'DELETE', null, $authToken);
    showTestResult("Eliminar rodal de prueba", 200, $deleteRodalResponse['code']);
}

// Eliminar proyecto de prueba
if ($testProjectId) {
    $deleteProjectResponse = makeRequest("$API_BASE_URL/projects/$testProjectId", 'DELETE', null, $authToken);
    showTestResult("Eliminar proyecto de prueba", 200, $deleteProjectResponse['code']);
}

echo "\n🎉 PRUEBAS COMPLETADAS 🎉\n";
echo "========================\n";
echo "Todas las funcionalidades de la API de datos de campo han sido probadas.\n";
echo "Revise los resultados arriba para verificar que todo funcione correctamente.\n\n";

echo "📋 RESUMEN DE FUNCIONALIDADES PROBADAS:\n";
echo "- ✅ Sincronización masiva de datos de campo\n";
echo "- ✅ Validación de datos forestales (DAP, altura, coordenadas GPS)\n";
echo "- ✅ Procesamiento de lotes de datos de árboles\n";
echo "- ✅ Manejo de errores y rollback en caso de fallo\n";
echo "- ✅ Marcado de registros como sincronizados\n";
echo "- ✅ Consulta de datos por rodal con paginación\n";
echo "- ✅ Consulta de registros específicos\n";
echo "- ✅ Actualización de registros existentes\n";
echo "- ✅ Validación de permisos por usuario\n";
echo "- ✅ Detección de valores atípicos\n";
echo "- ✅ Estadísticas de calidad de datos\n";
echo "- ✅ Manejo de límites de lote\n";
echo "- ✅ Autenticación y autorización\n";

?>