<?php
/**
 * api/auth-google.php — Google OAuth 2.0 callback
 *
 * Flow:
 *   1. Google redirects here with ?code=xxx&admin=1
 *   2. We exchange the code for tokens
 *   3. We fetch the user's Google profile (email, name, google_id)
 *   4. If ?admin=1: look up fb_users by email → log in as admin
 *      Otherwise: look up bk_users by email → log in as customer
 *   5. Redirect to the appropriate dashboard
 *
 * Required in config.php:
 *   define('GOOGLE_CLIENT_ID',     'your-client-id.apps.googleusercontent.com');
 *   define('GOOGLE_CLIENT_SECRET', 'your-client-secret');
 */

require_once dirname(__DIR__) . '/lib.php';
session_start_safe();

// ── Helpers ───────────────────────────────────────────────────
function google_fail(string $msg, bool $isAdmin): void {
    $page = $isAdmin ? '../admin.php' : '../login.php';
    header('Location: ' . $page . '?google_error=' . urlencode($msg));
    exit;
}

function google_http(string $url, array $post = []): array {
    // Prefer cURL on shared hosting (better TLS compatibility than file_get_contents)
    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
        if ($post) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
        }
        $body = curl_exec($ch);
        $err  = curl_error($ch);
        $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($body === false) return ['error' => 'HTTP request failed', 'detail' => $err ?: 'unknown'];
        $j = json_decode($body, true);
        if (is_array($j)) return $j;
        return ['error' => 'Invalid JSON response', 'http_code' => $code, 'raw' => substr((string)$body, 0, 400)];
    }

    $opts = [
        'http' => [
            'method'  => $post ? 'POST' : 'GET',
            'header'  => "Content-Type: application/x-www-form-urlencoded\r\n",
            'content' => $post ? http_build_query($post) : null,
            'ignore_errors' => true,
        ],
        'ssl' => ['verify_peer' => true, 'verify_peer_name' => true],
    ];
    $body = file_get_contents($url, false, stream_context_create($opts));
    if ($body === false) return ['error' => 'HTTP request failed'];
    return json_decode($body, true) ?? ['error' => 'Invalid JSON response', 'raw' => substr((string)$body, 0, 400)];
}

// ── Validate required config ──────────────────────────────────
$isAdmin = !empty($_GET['admin']);
$googleClientId = defined('GOOGLE_CLIENT_ID') ? trim((string)GOOGLE_CLIENT_ID) : '';
$googleClientSecret = defined('GOOGLE_CLIENT_SECRET') ? trim((string)GOOGLE_CLIENT_SECRET) : '';
if ($googleClientId === '' || $googleClientSecret === '') {
    google_fail('Google sign-in is not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in config.php.', $isAdmin);
}
$code    = $_GET['code']  ?? '';
$error   = $_GET['error'] ?? '';

if ($error) {
    google_fail('Google sign-in was cancelled or denied.', $isAdmin);
}
if (!$code) {
    google_fail('Missing authorization code from Google.', $isAdmin);
}

// ── Exchange code for access token ───────────────────────────
$redirectUri = rtrim(APP_URL, '/') . '/api/auth-google.php' . ($isAdmin ? '?admin=1' : '');

$tokenData = google_http('https://oauth2.googleapis.com/token', [
    'code'          => $code,
    'client_id'     => $googleClientId,
    'client_secret' => $googleClientSecret,
    'redirect_uri'  => $redirectUri,
    'grant_type'    => 'authorization_code',
]);

if (!empty($tokenData['error'])) {
    error_log('Google token error: ' . json_encode($tokenData));
    $desc = $tokenData['error_description'] ?? ($tokenData['detail'] ?? $tokenData['error']);
    google_fail('Google token error: ' . (string)$desc, $isAdmin);
}

$accessToken = $tokenData['access_token'] ?? '';
if (!$accessToken) {
    google_fail('No access token returned by Google.', $isAdmin);
}

// ── Fetch Google user profile ─────────────────────────────────
$profile = google_http(
    'https://www.googleapis.com/oauth2/v3/userinfo',
    // GET request — pass token in URL
);
// Refetch as GET with Authorization header
$ctx = stream_context_create(['http' => [
    'method' => 'GET',
    'header' => "Authorization: Bearer $accessToken\r\n",
    'ignore_errors' => true,
], 'ssl' => ['verify_peer' => true]]);
$profileJson = file_get_contents('https://www.googleapis.com/oauth2/v3/userinfo', false, $ctx);
$profile = json_decode($profileJson, true) ?? [];

$googleId = $profile['sub']             ?? '';
$email    = strtolower(trim($profile['email'] ?? ''));
$name     = trim($profile['name']       ?? '');
$verified = !empty($profile['email_verified']);

if (!$email || !$googleId) {
    google_fail('Could not retrieve your email from Google.', $isAdmin);
}
if (!$verified) {
    google_fail('Your Google account email is not verified.', $isAdmin);
}

$pdo = db();

// ── ADMIN flow ────────────────────────────────────────────────
if ($isAdmin) {
    // Admin must already have an account in fb_users — we do NOT auto-create admins
    $stmt = $pdo->prepare('SELECT id, username, email, role, is_active FROM fb_users WHERE email = ? LIMIT 1');
    $stmt->execute([$email]);
    $user = $stmt->fetch();

    if (!$user) {
        // First-login bootstrap: allow auto-create ONLY for configured ADMIN_EMAIL.
        $allowedAdminEmail = defined('ADMIN_EMAIL') ? strtolower(trim((string)ADMIN_EMAIL)) : '';
        if ($allowedAdminEmail && $email === $allowedAdminEmail) {
            $username = $name ?: 'Admin';
            $pdo->prepare('INSERT INTO fb_users (username, email, password_hash, role, is_active, google_id) VALUES (?, ?, ?, "admin", 1, ?)')
                ->execute([$username, $email, password_hash(bin2hex(random_bytes(16)), PASSWORD_BCRYPT), $googleId]);
            $stmt = $pdo->prepare('SELECT id, username, email, role, is_active FROM fb_users WHERE email = ? LIMIT 1');
            $stmt->execute([$email]);
            $user = $stmt->fetch();
        } else {
            google_fail('No admin account found for this Google email. Use your configured admin email.', true);
        }
    }
    if (!$user['is_active']) {
        google_fail('Your admin account is inactive. Contact your administrator.', true);
    }

    // Optionally store google_id if column exists
    try {
        $pdo->prepare('UPDATE fb_users SET google_id = ? WHERE id = ?')->execute([$googleId, $user['id']]);
    } catch (Throwable $e) { /* column may not exist yet — safe to ignore */ }

    session_regenerate_id(true);
    $_SESSION['admin_authed']  = true;
    $_SESSION['admin_time']    = time();
    $_SESSION['admin_user_id'] = (int)$user['id'];
    $_SESSION['admin_name']    = $user['username'];
    $_SESSION['admin_email']   = $user['email'];
    $_SESSION['admin_role']    = $user['role'];

    header('Location: ../admin.php');
    exit;
}

// ── CUSTOMER flow ─────────────────────────────────────────────
$stmt = $pdo->prepare('SELECT id, email FROM bk_users WHERE email = ? LIMIT 1');
$stmt->execute([$email]);
$user = $stmt->fetch();

if (!$user) {
    // Auto-create customer account via Google
    $pdo->prepare('INSERT INTO bk_users (email, password_hash, email_verified_at) VALUES (?, ?, NOW())')
        ->execute([$email, password_hash(bin2hex(random_bytes(16)), PASSWORD_BCRYPT)]);
    $userId = (int)$pdo->lastInsertId();

    // Create bk_customers record
    $pdo->prepare('INSERT INTO bk_customers (user_id, email, name) VALUES (?, ?, ?)')->execute([$userId, $email, $name]);
} else {
    $userId = (int)$user['id'];
    // Ensure email is verified
    $pdo->prepare('UPDATE bk_users SET email_verified_at = COALESCE(email_verified_at, NOW()) WHERE id = ?')->execute([$userId]);
    // Update customer name if blank
    $pdo->prepare('UPDATE bk_customers SET name = COALESCE(NULLIF(name,""), ?) WHERE user_id = ?')->execute([$name, $userId]);
}

session_regenerate_id(true);
$_SESSION['bk_user_id']    = $userId;
$_SESSION['bk_user_email'] = $email;
$_SESSION['bk_user_time']  = time();

header('Location: ../customer/dashboard.php');
exit;