<?php
/**
 * Data Deletion Callback — requerido por Meta para apps con WhatsApp/Facebook.
 *
 * Meta envía un POST con un signed_request cuando un usuario solicita
 * borrar sus datos desde Facebook. Aunque Vale usa Google OAuth (no Facebook Login),
 * Meta exige este endpoint para verificar la app en el panel de desarrolladores.
 *
 * Especificación: https://developers.facebook.com/docs/development/create-an-app/app-dashboard/data-deletion-callback
 *
 * Flujo:
 *   1. Meta POST /data-deletion con signed_request
 *   2. Verificamos la firma HMAC-SHA256 con META_APP_SECRET
 *   3. Extraemos el user_id de Meta del payload
 *   4. Buscamos si ese user_id está vinculado a algún user nuestro
 *   5. Marcamos o eliminamos los datos; registramos el request
 *   6. Respondemos JSON con url de status y código de confirmación
 *
 * Para GET /data-deletion/status?id=XXXX:
 *   Devolvemos el estado del request de borrado.
 */

if (count(get_included_files()) === 1) { http_response_code(403); exit('Forbidden'); }

$uri    = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
$db     = DB::connect();

// ── GET /data-deletion/status?id=XXXX ────────────────────────────────────────
if ($method === 'GET' && strpos($uri, '/data-deletion/status') === 0) {
    header('Content-Type: application/json; charset=utf-8');
    $code = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['id'] ?? '');
    if ($code === '') {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => 'Missing id']);
        exit;
    }
    try {
        $stmt = $db->prepare(
            "SELECT estado, created_at FROM data_deletion_requests WHERE confirmation_code = :c LIMIT 1"
        );
        $stmt->execute([':c' => $code]);
        $row = $stmt->fetch();
    } catch (Throwable $_e) {
        $row = null;
    }
    if (!$row) {
        echo json_encode(['status' => 'not_found', 'confirmation_code' => $code]);
    } else {
        echo json_encode([
            'confirmation_code' => $code,
            'status'            => $row['estado'] ?? 'pending',
            'requested_at'      => $row['created_at'] ?? '',
        ]);
    }
    exit;
}

// ── GET /data-deletion — Página pública de eliminación de datos ──────────────
if ($method === 'GET' && $uri === '/data-deletion') {
    require dirname(__DIR__) . '/views/data_deletion.php';
    exit;
}

// ── POST /data-deletion — Meta envía el signed_request ───────────────────────
if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method Not Allowed']);
    exit;
}

header('Content-Type: application/json; charset=utf-8');

$appSecret = getenv('META_APP_SECRET') ?: '';
$rawInput  = $_POST['signed_request'] ?? '';

// Algunas implementaciones lo mandan como JSON body (no form-encoded)
if ($rawInput === '') {
    $body     = json_decode(file_get_contents('php://input'), true);
    $rawInput = $body['signed_request'] ?? '';
}

if ($rawInput === '') {
    http_response_code(400);
    echo json_encode(['error' => 'Missing signed_request']);
    exit;
}

// ── 1. Parsear y verificar la firma ──────────────────────────────────────────
$parts = explode('.', $rawInput, 2);
if (count($parts) !== 2) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid signed_request format']);
    exit;
}

[$encodedSig, $encodedPayload] = $parts;

// base64url → base64 estándar
$sig     = base64_decode(strtr($encodedSig,     '-_', '+/'));
$payload = json_decode(base64_decode(strtr($encodedPayload, '-_', '+/')), true);

if (!is_array($payload)) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid payload']);
    exit;
}

// Verificar HMAC-SHA256
if ($appSecret !== '') {
    $expected = hash_hmac('sha256', $encodedPayload, $appSecret, true);
    if (!hash_equals($expected, $sig)) {
        http_response_code(403);
        echo json_encode(['error' => 'Invalid signature']);
        exit;
    }
}

$metaUserId = (string)($payload['user_id'] ?? '');
if ($metaUserId === '') {
    http_response_code(400);
    echo json_encode(['error' => 'Missing user_id in payload']);
    exit;
}

// ── 2. Generar código de confirmación único ────────────────────────────────
$confirmationCode = bin2hex(random_bytes(16));

// ── 3. Registrar el request y procesar el borrado ─────────────────────────
try {
    // Asegurar que la tabla existe (se crea aquí si falta)
    $db->exec(
        "CREATE TABLE IF NOT EXISTS data_deletion_requests (
            id                INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            meta_user_id      VARCHAR(64)  NOT NULL,
            confirmation_code VARCHAR(64)  NOT NULL,
            estado            VARCHAR(20)  NOT NULL DEFAULT 'completed',
            user_id_local     BIGINT UNSIGNED NULL,
            created_at        TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY uq_code (confirmation_code),
            INDEX idx_meta_uid (meta_user_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
    );

    // Buscar si tenemos un user local vinculado a ese meta_user_id.
    // (En Vale usamos Google OAuth, así que probablemente no hay vínculo directo.
    //  De todas formas hacemos un intento honesto de búsqueda.)
    $localUserId = null;
    try {
        $stmt = $db->prepare(
            "SELECT id FROM users WHERE meta_user_id = :mid LIMIT 1"
        );
        $stmt->execute([':mid' => $metaUserId]);
        $localUserId = $stmt->fetchColumn() ?: null;
    } catch (Throwable $_e) {
        // Columna puede no existir — ignorar
    }

    // Si encontramos un usuario local, anonimizamos sus datos
    // (borramos info personal, preservamos el tenant para no romper otros users)
    if ($localUserId) {
        try {
            $db->prepare(
                "UPDATE users SET
                    name       = 'Usuario eliminado',
                    email      = CONCAT('deleted_', id, '@deleted.invalid'),
                    google_sub = NULL,
                    avatar_url = NULL
                 WHERE id = :uid"
            )->execute([':uid' => $localUserId]);
        } catch (Throwable $e) {
            error_log('[data_deletion] anonymize user error: ' . $e->getMessage());
        }
    }

    // Registrar el request
    $db->prepare(
        "INSERT INTO data_deletion_requests
            (meta_user_id, confirmation_code, estado, user_id_local)
         VALUES (:mid, :code, 'completed', :uid)"
    )->execute([
        ':mid'  => $metaUserId,
        ':code' => $confirmationCode,
        ':uid'  => $localUserId,
    ]);

} catch (Throwable $e) {
    error_log('[data_deletion] DB error: ' . $e->getMessage());
    // Respondemos OK de todas formas — Meta no debe recibir un error
    // por un problema interno nuestro. El request se loguea en error_log.
}

// ── 4. Responder a Meta ──────────────────────────────────────────────────────
$scheme  = (!empty($_SERVER['HTTPS']) || ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https') ? 'https' : 'http';
$baseUrl = $scheme . '://' . ($_SERVER['HTTP_HOST'] ?? 'valeai.app');

echo json_encode([
    'url'               => "$baseUrl/data-deletion/status?id=$confirmationCode",
    'confirmation_code' => $confirmationCode,
]);
