<?php
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/kyc_helpers.php';

// Protege el endpoint con un token compartido en la query string.
$token = $_GET['token'] ?? '';
if (DIDIT_WEBHOOK_TOKEN && $token !== DIDIT_WEBHOOK_TOKEN) {
    http_response_code(403);
    echo 'Forbidden';
    exit;
}

$db = getDatabaseConnection();

$raw = file_get_contents('php://input');
$data = json_decode($raw, true) ?: [];

// Fallback: algunos callbacks llegan como GET con query string.
if (empty($data) && $_SERVER['REQUEST_METHOD'] === 'GET') {
    $data = [
        'status' => $_GET['status'] ?? $_GET['result'] ?? null,
        'verificationSessionId' => $_GET['verificationSessionId'] ?? $_GET['session_id'] ?? $_GET['sessionId'] ?? null,
        'vendor_data' => $_GET['vendor_data'] ?? $_GET['vendorData'] ?? null,
        'user_id' => $_GET['user_id'] ?? $_GET['userId'] ?? $_GET['external_id'] ?? $_GET['externalId'] ?? null
    ];
}
 
$userId = null;
$possibleIds = [
    $data['external_id'] ?? $data['externalId'] ?? null,
    $data['custom_id'] ?? $data['customId'] ?? null,
    $data['user_id'] ?? $data['userId'] ?? null,
    $data['vendor_data'] ?? $data['vendorData'] ?? null
];
foreach ($possibleIds as $pid) {
    if ($pid !== null && ctype_digit((string)$pid)) {
        $userId = (int)$pid;
        break;
    }
}

// Si no hay userId pero tenemos sessionId, intentamos consultarlo.
$sessionId = $data['id'] ?? $data['request_id'] ?? $data['verification_id'] ?? $data['verificationSessionId'] ?? $data['session_id'] ?? $data['sessionId'] ?? '';

// Intento 1: buscar usuario por sessionId en la BD.
if (!$userId && $sessionId) {
    try {
        $stmt = $db->prepare('SELECT id FROM usuarios WHERE kyc_id_sesion = ? LIMIT 1');
        if ($stmt) {
            $stmt->bind_param('s', $sessionId);
            $stmt->execute();
            $res = $stmt->get_result();
            $row = $res->fetch_assoc();
            if ($row && isset($row['id'])) {
                $userId = (int)$row['id'];
            }
        }
    } catch (Throwable $e) {
        error_log('Didit webhook db lookup error: ' . $e->getMessage());
    }
}
 
$sessionDetails = null;
$decisionDetails = null;
// Intento 2: si aun no hay userId y tenemos sessionId, pedir detalles a Didit.
if (!$userId && $sessionId && DIDIT_API_KEY) {
    try {
        $sessionDetails = diditRequest('GET', '/v2/session/' . urlencode($sessionId) . '/', null);
        $pid = $sessionDetails['vendor_data'] ?? $sessionDetails['vendorData'] ?? $sessionDetails['user_id'] ?? $sessionDetails['userId'] ?? $sessionDetails['external_id'] ?? $sessionDetails['externalId'] ?? null;
        if ($pid !== null && ctype_digit((string)$pid)) {
            $userId = (int)$pid;
        }
        if (empty($data['status']) && !empty($sessionDetails['status'])) {
            $data['status'] = $sessionDetails['status'];
        }
    } catch (Throwable $e) {
        error_log('Didit webhook lookup error: ' . $e->getMessage());
    }
}

// Intenta traer decision details (tienen identidad enriquecida).
if ($sessionId && DIDIT_API_KEY) {
    try {
        $decisionDetails = diditRequest('GET', '/v2/session/' . urlencode($sessionId) . '/decision/', null);
    } catch (Throwable $e) {
        error_log('Didit webhook decision lookup error: ' . $e->getMessage());
    }
}

if (!$userId) {
    $keys = [];
    foreach ($data as $k => $v) {
        if ($v !== null && $v !== '') {
            $keys[] = $k;
        }
    }
    error_log('Didit webhook without user id; session=' . $sessionId . ' keys=' . implode(',', $keys));
    http_response_code(400);
    echo 'No user id';
    exit;
}

// Trae los datos de identidad del usuario para comparar.
$userInfo = null;
try {
    $stmtUser = $db->prepare('SELECT nombre_completo, numero_documento, tipo_documento, pais FROM usuarios WHERE id = ? LIMIT 1');
    if ($stmtUser) {
        $stmtUser->bind_param('i', $userId);
        $stmtUser->execute();
        $resUser = $stmtUser->get_result();
        $userInfo = $resUser->fetch_assoc();
    }
} catch (Throwable $e) {
    error_log('Didit webhook user fetch error: ' . $e->getMessage());
}

$statusRaw = strtolower((string)($data['status'] ?? $data['result'] ?? $data['decision'] ?? ''));
$reason = $data['reason'] ?? $data['failure_reason'] ?? $data['code'] ?? '';

$normalized = 'pendiente';
if (in_array($statusRaw, ['approved', 'verified', 'success', 'completed', 'passed'], true)) {
    $normalized = 'verificado';
} elseif (in_array($statusRaw, ['rejected', 'failed', 'declined', 'cancelled', 'canceled', 'error'], true)) {
    $normalized = 'rechazado';
    if (is_array($reason)) {
        $reason = implode(';', array_filter($reason));
    }
}

// Si ya tenemos sessionId y aun no se pidieron detalles, hazlo para comparar identidad.
if ($sessionId && !$sessionDetails && DIDIT_API_KEY) {
    try {
        $sessionDetails = diditRequest('GET', '/v2/session/' . urlencode($sessionId) . '/', null);
    } catch (Throwable $e) {
        error_log('Didit webhook lookup error (post): ' . $e->getMessage());
    }
}

// Comparar identidad capturada vs. registro si se verifico y hay datos.
if ($normalized === 'verificado' && $userInfo) {
    $issues = [];
    $stripDoc = function ($v) {
        return strtolower(preg_replace('/[^0-9a-z]/i', '', (string)$v));
    };
    $normText = function ($v) {
        return strtolower(trim(preg_replace('/\s+/', ' ', (string)$v)));
    };
    $mapDocType = function ($val) {
        $v = strtoupper(trim((string)$val));
        $map = [
            'IDENTITY CARD' => 'CC',
            'ID CARD' => 'CC',
            'ID' => 'CC',
            'CEDULA' => 'CC',
            'CEDULA DE CIUDADANIA' => 'CC',
            'CEDULA DE CIUDADANÍA' => 'CC',
            'NATIONAL ID' => 'CC',
            'NATIONAL_ID' => 'CC',
            'NATIONAL ID CARD' => 'CC',
            'NATIONAL_ID_CARD' => 'CC',
            'PASSPORT' => 'PA',
            'PASAPORTE' => 'PA',
            'DRIVER LICENSE' => 'LC',
            'DRIVER\'S LICENSE' => 'LC',
            'DRIVER LICENSES' => 'LC',
            'DRIVER LICENCE' => 'LC',
            'DRIVING LICENCE' => 'LC',
            'DRIVING LICENSE' => 'LC',
            'DRIVER' => 'LC',
            'LICENSE' => 'LC',
            'LICENCIA' => 'LC',
            'FOREIGN ID' => 'CE',
            'FOREIGN_ID' => 'CE',
            'FOREIGNER ID' => 'CE', 
            'FOREIGNER_ID' => 'CE',
            'CEDULA DE EXTRANJERIA' => 'CE',
            'CEDULA DE EXTRANJERÍA' => 'CE',
            'CE' => 'CE'
        ];
        return $map[$v] ?? $v;
    };

    // Fuente primaria: decision -> id_verification
    $idv = $decisionDetails['id_verification'] ?? null;
    $didDoc = null;
    $didType = null;
    $didCountry = null;
    $didName = null;

    if ($idv) {
        $didDoc = $idv['document_number'] ?? $idv['personal_number'] ?? null;
        $didType = $idv['document_type'] ?? null;
        $didCountry = $idv['issuing_state_name'] ?? $idv['issuing_state'] ?? $idv['nationality'] ?? null;
        if (empty($didCountry) && !empty($idv['country'])) {
            $didCountry = $idv['country'];
        }
        $didName = $idv['full_name'] ?? trim(($idv['first_name'] ?? '') . ' ' . ($idv['last_name'] ?? ''));
    } elseif ($sessionDetails) {
        $didDoc = $sessionDetails['document_number'] ?? ($sessionDetails['document']['number'] ?? ($sessionDetails['document']['document_number'] ?? null));
        $didType = $sessionDetails['document_type'] ?? ($sessionDetails['document']['type'] ?? null);
        $didCountry = $sessionDetails['country'] ?? ($sessionDetails['document']['country'] ?? ($sessionDetails['document']['nationality'] ?? null));
        $didName = $sessionDetails['full_name'] ?? $sessionDetails['name'] ?? ($sessionDetails['user']['name'] ?? null);
    }

    if (!empty($userInfo['numero_documento']) && $didDoc) {
        if ($stripDoc($userInfo['numero_documento']) !== $stripDoc($didDoc)) {
            $issues[] = 'numero de documento';
        }
    }
    if (!empty($userInfo['tipo_documento']) && $didType) {
        if (strtoupper($userInfo['tipo_documento']) !== $mapDocType($didType)) {
            $issues[] = 'tipo de documento';
        }
    }
    if (!empty($userInfo['pais']) && $didCountry) {
        if ($normText($userInfo['pais']) !== $normText($didCountry)) {
            $issues[] = 'pais/nacionalidad';
        }
    }
    if (!empty($userInfo['nombre_completo']) && $didName) {
        if ($normText($userInfo['nombre_completo']) !== $normText($didName)) {
            $issues[] = 'nombre';
        }
    }

    if (!empty($issues)) {
        $normalized = 'rechazado';
        $reason = 'No coincide ' . implode(', ', $issues) . ' con el registro.';
    }
}

try {
    setUserKycStatus($db, $userId, $normalized, $sessionId, $reason ?: null);
} catch (Throwable $e) {
    // No se registra el payload completo para evitar PII.
    error_log('Didit webhook error: ' . $e->getMessage());
    http_response_code(500);
    echo 'Server error';
    exit;
}

// Si viene como callback via navegador (GET), redirige al flujo de pago/subscripcion.
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $msg = 'Identidad verificada, continua con el pago.';
    if ($normalized !== 'verificado') {
        $msg = 'Verificacion procesada (' . $normalized . ').';
    }
    header('Location: subscription?message=' . urlencode($msg));
    exit;
}

http_response_code(200);
echo json_encode(['received' => true]);
