<?php
// Archivo para manejar la migración de URLs de Google Maps a direcciones reales
require_once '../../modelos/Cliente.php';

// Crear instancia del modelo
$cliente = new Cliente($conn);

switch ($tipo) {
    case 'migrarDireccionesURL':
        try {
            // Obtener clientes que tienen URL en el campo url
            $query = "SELECT id, url, nombre_comercial
                     FROM clientes
                     WHERE url IS NOT NULL
                     AND url != ''
                     AND (url LIKE '%google.com/maps%'
                     OR url LIKE '%maps.google%'
                     OR url LIKE '%goo.gl/maps%')";

            $stmt = $conn->prepare($query);
            $stmt->execute();
            $clientesConURL = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $resultados = [
                'procesados' => 0,
                'exitosos' => 0,
                'fallidos' => 0,
                'detalles' => []
            ];

            foreach ($clientesConURL as $clienteData) {
                $resultado = procesarClienteURL($clienteData['id'], $clienteData['url'], $conn);
                $resultados['procesados']++;

                if ($resultado['success']) {
                    $resultados['exitosos']++;
                } else {
                    $resultados['fallidos']++;
                }

                $resultados['detalles'][] = [
                    'cliente_id' => $clienteData['id'],
                    'nombre' => $clienteData['nombre_comercial'],
                    'resultado' => $resultado
                ];
            }

            sendResponse(true, "Migración completada", $resultados);
        } catch (Exception $e) {
            error_log("Error en migración de direcciones: " . $e->getMessage());
            sendResponse(false, "Error en migración: " . $e->getMessage());
        }
        break;

    case 'procesarDireccionURL':
        try {
            $clienteId = isset($datapost['cliente_id']) ? (int)$datapost['cliente_id'] : 0;

            if ($clienteId <= 0) {
                sendResponse(false, "ID de cliente inválido");
            }

            // Obtener la URL actual del cliente
            $query = "SELECT url FROM clientes WHERE id = :id";
            $stmt = $conn->prepare($query);
            $stmt->bindParam(':id', $clienteId);
            $stmt->execute();
            $clienteData = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$clienteData || empty($clienteData['url'])) {
                sendResponse(false, "Cliente no encontrado o sin URL");
            }

            $resultado = procesarClienteURL($clienteId, $clienteData['url'], $conn);

            if ($resultado['success']) {
                sendResponse(true, "Dirección procesada exitosamente", $resultado);
            } else {
                sendResponse(false, $resultado['error'], $resultado);
            }
        } catch (Exception $e) {
            error_log("Error procesando dirección URL: " . $e->getMessage());
            sendResponse(false, "Error procesando dirección: " . $e->getMessage());
        }
        break;

    case 'obtenerClientesConURL':
        try {
            $query = "SELECT
                        c.id,
                        c.codigo,
                        c.nombre_comercial,
                        c.url as url_actual,
                        CONCAT(c.nombre, ' ', COALESCE(c.apellidos, '')) as nombre_completo
                     FROM clientes c
                     WHERE c.url IS NOT NULL
                     AND c.url != ''
                     AND (c.url LIKE '%google.com/maps%'
                     OR c.url LIKE '%maps.google%'
                     OR c.url LIKE '%goo.gl/maps%')
                     ORDER BY c.id";

            $stmt = $conn->prepare($query);
            $stmt->execute();
            $clientes = $stmt->fetchAll(PDO::FETCH_ASSOC);

            sendResponse(true, "Clientes con URL obtenidos", [
                'total' => count($clientes),
                'clientes' => $clientes
            ]);
        } catch (Exception $e) {
            error_log("Error obteniendo clientes con URL: " . $e->getMessage());
            sendResponse(false, "Error obteniendo clientes: " . $e->getMessage());
        }
        break;
}

/**
 * Función para procesar un cliente con URL de Google Maps
 */
function procesarClienteURL($clienteId, $urlDireccion, $conn)
{
    try {
        // Extraer coordenadas de la URL
        $coordenadas = extraerCoordenadas($urlDireccion);

        if (!$coordenadas) {
            return [
                'success' => false,
                'error' => 'No se pudieron extraer las coordenadas de la URL'
            ];
        }

        // Obtener dirección usando geocoding inverso
        $direccionData = obtenerDireccionDesdeCoordenadas($coordenadas['lat'], $coordenadas['lng']);

        if (!$direccionData) {
            // Si no se puede obtener la dirección, al menos guardar las coordenadas
            $direccionData = [
                'direccion' => 'Coordenadas: ' . $coordenadas['lat'] . ', ' . $coordenadas['lng'],
                'codigo_postal' => null,
                'pais' => 'México'
            ];
        }

        // Actualizar el cliente en la base de datos y limpiar el campo url
        $query = "UPDATE clientes SET
                    direccion = :direccion,
                    latitud = :latitud,
                    longitud = :longitud,
                    codigo_postal = :codigo_postal,
                    pais = :pais,
                    url = NULL,
                    updated_at = NOW()
                  WHERE id = :id";

        $stmt = $conn->prepare($query);
        $stmt->bindParam(':direccion', $direccionData['direccion']);
        $stmt->bindParam(':latitud', $coordenadas['lat']);
        $stmt->bindParam(':longitud', $coordenadas['lng']);
        $stmt->bindParam(':codigo_postal', $direccionData['codigo_postal']);
        $stmt->bindParam(':pais', $direccionData['pais']);
        $stmt->bindParam(':id', $clienteId);

        if ($stmt->execute()) {
            return [
                'success' => true,
                'direccion' => $direccionData['direccion'],
                'latitud' => $coordenadas['lat'],
                'longitud' => $coordenadas['lng'],
                'codigo_postal' => $direccionData['codigo_postal'],
                'pais' => $direccionData['pais'],
                'url_eliminada' => true
            ];
        } else {
            return [
                'success' => false,
                'error' => 'Error actualizando la base de datos'
            ];
        }
    } catch (Exception $e) {
        error_log("Error procesando cliente URL: " . $e->getMessage());
        return [
            'success' => false,
            'error' => $e->getMessage()
        ];
    }
}

/**
 * Función para extraer coordenadas de una URL de Google Maps
 */
function extraerCoordenadas($url)
{
    // Patrones para extraer coordenadas de diferentes formatos de URLs de Google Maps

    // Patrón 1: URLs con @latitud,longitud
    if (preg_match('/@(-?\d+\.\d+),(-?\d+\.\d+)/', $url, $matches)) {
        return [
            'lat' => (float)$matches[1],
            'lng' => (float)$matches[2]
        ];
    }

    // Patrón 2: URLs con coordenadas en formato place/lat°min'seg"N+lon°min'seg"W
    if (preg_match('/place\/(\d+)%C2%B0(\d+)\'([\d.]+)%22([NS])\+(\d+)%C2%B0(\d+)\'([\d.]+)%22([EW])/', $url, $matches)) {
        // Convertir grados, minutos, segundos a decimal
        $lat = $matches[1] + ($matches[2] / 60) + ($matches[3] / 3600);
        if ($matches[4] == 'S') $lat = -$lat;

        $lng = $matches[5] + ($matches[6] / 60) + ($matches[7] / 3600);
        if ($matches[8] == 'W') $lng = -$lng;

        return [
            'lat' => $lat,
            'lng' => $lng
        ];
    }

    // Patrón 3: URLs con !3d (latitud) y !4d (longitud)
    if (preg_match('/!3d(-?\d+\.\d+).*!4d(-?\d+\.\d+)/', $url, $matches)) {
        return [
            'lat' => (float)$matches[1],
            'lng' => (float)$matches[2]
        ];
    }

    // Patrón 4: URLs con ll= (latitud,longitud)
    if (preg_match('/ll=(-?\d+\.\d+),(-?\d+\.\d+)/', $url, $matches)) {
        return [
            'lat' => (float)$matches[1],
            'lng' => (float)$matches[2]
        ];
    }

    // Patrón 5: URLs con q= (query con coordenadas)
    if (preg_match('/q=(-?\d+\.\d+),(-?\d+\.\d+)/', $url, $matches)) {
        return [
            'lat' => (float)$matches[1],
            'lng' => (float)$matches[2]
        ];
    }

    return false;
}

/**
 * Función para obtener dirección desde coordenadas usando Nominatim (OpenStreetMap)
 */
function obtenerDireccionDesdeCoordenadas($lat, $lng)
{
    try {
        // Usar Nominatim de OpenStreetMap (gratuito y sin límites estrictos)
        $url = "https://nominatim.openstreetmap.org/reverse?format=json&lat={$lat}&lon={$lng}&zoom=18&addressdetails=1&accept-language=es";

        // Configurar contexto con User-Agent (requerido por Nominatim)
        $opts = [
            "http" => [
                "method" => "GET",
                "header" => "User-Agent: Sistema de Rutas v1.0\r\n"
            ]
        ];

        $context = stream_context_create($opts);
        $response = @file_get_contents($url, false, $context);

        if ($response === false) {
            error_log("Error obteniendo dirección desde Nominatim");
            return false;
        }

        $data = json_decode($response, true);

        if (!$data || !isset($data['address'])) {
            return false;
        }

        // Construir la dirección desde los componentes
        $address = $data['address'];
        $direccionComponentes = [];

        // Agregar componentes de dirección en orden
        if (isset($address['road'])) {
            $direccionComponentes[] = $address['road'];
        }
        if (isset($address['house_number'])) {
            $direccionComponentes[] = '#' . $address['house_number'];
        }
        if (isset($address['suburb']) || isset($address['neighbourhood'])) {
            $direccionComponentes[] = $address['suburb'] ?? $address['neighbourhood'];
        }
        if (isset($address['city']) || isset($address['town']) || isset($address['village'])) {
            $direccionComponentes[] = $address['city'] ?? $address['town'] ?? $address['village'];
        }
        if (isset($address['state'])) {
            $direccionComponentes[] = $address['state'];
        }

        // Si no hay componentes específicos, usar display_name
        if (empty($direccionComponentes) && isset($data['display_name'])) {
            $direccion = $data['display_name'];
        } else {
            $direccion = implode(', ', $direccionComponentes);
        }

        return [
            'direccion' => $direccion,
            'codigo_postal' => $address['postcode'] ?? null,
            'pais' => $address['country'] ?? 'México'
        ];
    } catch (Exception $e) {
        error_log("Error en geocoding inverso: " . $e->getMessage());
        return false;
    }
}

// Función alternativa usando Google Geocoding API (requiere API key)
function obtenerDireccionDesdeCoordenadasGoogle($lat, $lng, $apiKey = null)
{
    if (!$apiKey) {
        return false;
    }

    try {
        $url = "https://maps.googleapis.com/maps/api/geocode/json?latlng={$lat},{$lng}&key={$apiKey}&language=es";

        $response = @file_get_contents($url);

        if ($response === false) {
            return false;
        }

        $data = json_decode($response, true);

        if ($data['status'] !== 'OK' || empty($data['results'])) {
            return false;
        }

        $result = $data['results'][0];
        $codigoPostal = null;
        $pais = 'México';

        // Extraer código postal y país de los componentes
        foreach ($result['address_components'] as $component) {
            if (in_array('postal_code', $component['types'])) {
                $codigoPostal = $component['long_name'];
            }
            if (in_array('country', $component['types'])) {
                $pais = $component['long_name'];
            }
        }

        return [
            'direccion' => $result['formatted_address'],
            'codigo_postal' => $codigoPostal,
            'pais' => $pais
        ];
    } catch (Exception $e) {
        error_log("Error en Google Geocoding: " . $e->getMessage());
        return false;
    }
}
