<?php
/**
 * Firebase: verify idToken (Identity Toolkit) + RTDB GET via service-account OAuth.
 * No Composer; requires PHP openssl + curl.
 */

function firebase_b64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function firebase_service_account_access_token($serviceAccountJsonPath, $scope = 'https://www.googleapis.com/auth/firebase.database https://www.googleapis.com/auth/userinfo.email') {
    if (!is_readable($serviceAccountJsonPath)) return ['error' => 'Service account JSON not readable: ' . $serviceAccountJsonPath];
    $sa = json_decode(file_get_contents($serviceAccountJsonPath), true);
    if (!is_array($sa) || empty($sa['private_key']) || empty($sa['client_email'])) return ['error' => 'Invalid service account JSON.'];
    $now = time();
    $header = json_encode(['typ' => 'JWT', 'alg' => 'RS256']);
    $claim = json_encode([
        'iss' => $sa['client_email'], 'sub' => $sa['client_email'], 'aud' => 'https://oauth2.googleapis.com/token',
        'iat' => $now, 'exp' => $now + 3600, 'scope' => trim((string) $scope),
    ]);
    $segments = firebase_b64url_encode($header) . '.' . firebase_b64url_encode($claim);
    $key = openssl_pkey_get_private($sa['private_key']);
    if ($key === false) return ['error' => 'Could not parse service account private_key.'];
    $sig = '';
    if (!openssl_sign($segments, $sig, $key, OPENSSL_ALGO_SHA256)) return ['error' => 'Could not sign JWT.'];
    $jwt = $segments . '.' . firebase_b64url_encode($sig);
    if (!function_exists('curl_init')) return ['error' => 'PHP curl extension required for Firebase admin.'];
    $ch = curl_init('https://oauth2.googleapis.com/token');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query(['grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt]),
        CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
    ]);
    $res = curl_exec($ch); curl_close($ch);
    if ($res === false) return ['error' => 'OAuth token request failed.'];
    $data = json_decode($res, true);
    if (empty($data['access_token'])) return ['error' => isset($data['error_description']) ? (string)$data['error_description'] : 'No access_token from Google.'];
    return ['access_token' => $data['access_token']];
}

function firebase_rtdb_url($databaseUrl, $path, $accessToken) {
    $databaseUrl = rtrim((string) $databaseUrl, '/');
    $enc = array_map('rawurlencode', explode('/', trim((string) $path, '/')));
    return $databaseUrl . '/' . implode('/', $enc) . '.json?access_token=' . rawurlencode($accessToken);
}

function firebase_rtdb_get($databaseUrl, $path, $accessToken) {
    if (!function_exists('curl_init')) return ['error' => 'PHP curl extension required.'];
    $ch = curl_init(firebase_rtdb_url($databaseUrl, $path, $accessToken));
    curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30]);
    $res = curl_exec($ch); $http = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
    if ($res === false) return ['error' => 'RTDB request failed.', 'http' => $http];
    if ($http >= 400) return ['error' => 'RTDB HTTP ' . $http, 'http' => $http, 'data' => null];
    if ($res === 'null') return ['data' => null, 'http' => $http];
    return ['data' => json_decode($res, true), 'http' => $http];
}

function firebase_rtdb_write($databaseUrl, $path, $accessToken, $method, $payload = null) {
    if (!function_exists('curl_init')) return ['error' => 'PHP curl extension required.'];
    $ch = curl_init(firebase_rtdb_url($databaseUrl, $path, $accessToken));
    $opts = [
        CURLOPT_CUSTOMREQUEST => strtoupper((string) $method),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    ];
    if ($payload !== null) $opts[CURLOPT_POSTFIELDS] = json_encode($payload, JSON_UNESCAPED_UNICODE);
    curl_setopt_array($ch, $opts);
    $res = curl_exec($ch); $http = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
    if ($res === false) return ['error' => 'RTDB write failed.', 'http' => $http];
    if ($http >= 400) return ['error' => 'RTDB HTTP ' . $http, 'http' => $http];
    return ['data' => json_decode($res, true), 'http' => $http];
}

function firebase_rtdb_patch($databaseUrl, $path, $accessToken, $payload) { return firebase_rtdb_write($databaseUrl, $path, $accessToken, 'PATCH', $payload); }
function firebase_rtdb_put($databaseUrl, $path, $accessToken, $payload) { return firebase_rtdb_write($databaseUrl, $path, $accessToken, 'PUT', $payload); }
function firebase_rtdb_post($databaseUrl, $path, $accessToken, $payload) { return firebase_rtdb_write($databaseUrl, $path, $accessToken, 'POST', $payload); }
function firebase_rtdb_delete($databaseUrl, $path, $accessToken) { return firebase_rtdb_write($databaseUrl, $path, $accessToken, 'DELETE', null); }

/**
 * Create Firebase Auth user (same as client createUserWithEmailAndPassword). Uses web API key, not service account.
 * @return array{uid?: string, idToken?: string, error?: string, firebaseCode?: string}
 */
function firebase_identity_sign_up_email($webApiKey, $email, $password) {
    $webApiKey = trim((string) $webApiKey);
    $email = trim((string) $email);
    if ($webApiKey === '' || $email === '' || $password === '') return ['error' => 'Email, password, and web API key are required.'];
    if (!function_exists('curl_init')) return ['error' => 'PHP curl extension required.'];
    $url = 'https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=' . rawurlencode($webApiKey);
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode(['email' => $email, 'password' => $password, 'returnSecureToken' => true]),
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
    ]);
    $res = curl_exec($ch);
    curl_close($ch);
    if ($res === false) return ['error' => 'signUp request failed.'];
    $data = json_decode($res, true);
    if (!is_array($data)) return ['error' => 'Invalid signUp response.'];
    if (!empty($data['localId'])) {
        return ['uid' => (string) $data['localId'], 'idToken' => (string) ($data['idToken'] ?? '')];
    }
    $msg = isset($data['error']['message']) ? (string) $data['error']['message'] : 'signUp failed.';
    $code = isset($data['error']['message']) ? (string) $data['error']['message'] : '';
    return ['error' => $msg, 'firebaseCode' => $code];
}

/**
 * Delete the account for the given idToken (rollback after failed RTDB writes).
 * @return array{ok?: true, error?: string}
 */
function firebase_identity_delete_account($webApiKey, $idToken) {
    $webApiKey = trim((string) $webApiKey);
    $idToken = trim((string) $idToken);
    if ($webApiKey === '' || $idToken === '') return ['error' => 'idToken and web API key required.'];
    if (!function_exists('curl_init')) return ['error' => 'PHP curl extension required.'];
    $url = 'https://identitytoolkit.googleapis.com/v1/accounts:delete?key=' . rawurlencode($webApiKey);
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode(['idToken' => $idToken]),
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
    ]);
    $res = curl_exec($ch);
    curl_close($ch);
    if ($res === false) return ['error' => 'delete account request failed.'];
    $data = json_decode($res, true);
    if (is_array($data) && empty($data['error'])) return ['ok' => true];
    $msg = is_array($data) && isset($data['error']['message']) ? (string) $data['error']['message'] : 'delete failed.';
    return ['error' => $msg];
}

function firebase_verify_id_token($idToken, $webApiKey) {
    $idToken = trim((string) $idToken); $webApiKey = trim((string) $webApiKey);
    if ($idToken === '' || $webApiKey === '') return ['error' => 'idToken and web API key are required.'];
    if (!function_exists('curl_init')) return ['error' => 'PHP curl extension required.'];
    $ch = curl_init('https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=' . rawurlencode($webApiKey));
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode(['idToken' => $idToken]),
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15,
    ]);
    $res = curl_exec($ch); curl_close($ch);
    if ($res === false) return ['error' => 'Could not verify idToken.'];
    $data = json_decode($res, true);
    if (!empty($data['users'][0]['localId'])) return ['uid' => (string) $data['users'][0]['localId']];
    return ['error' => isset($data['error']['message']) ? (string)$data['error']['message'] : 'Invalid or expired idToken.'];
}
