<?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 {
    $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],
    ];
    $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'];
}

// ── Validate required config ──────────────────────────────────
if (!defined('GOOGLE_CLIENT_ID') || !defined('GOOGLE_CLIENT_SECRET')) {
    die('Google OAuth not configured. Add GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET to config.php.');
}

$isAdmin = !empty($_GET['admin']);
$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'     => GOOGLE_CLIENT_ID,
    'client_secret' => GOOGLE_CLIENT_SECRET,
    'redirect_uri'  => $redirectUri,
    'grant_type'    => 'authorization_code',
]);

if (!empty($tokenData['error'])) {
    error_log('Google token error: ' . json_encode($tokenData));
    google_fail('Failed to get token from Google. Please try again.', $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) {
        google_fail('No admin account found for this Google email. Contact your administrator.', 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;