<?php
/**
 * Shared helpers for Dabil social sign-in.
 *  - tiny cURL wrappers
 *  - find-or-create a customer from a verified social identity
 *  - start the customer session (mirrors login.php exactly)
 *  - safe internal redirect (mirrors login.php)
 *
 * Robustness: this works WHETHER OR NOT auth/oauth_migration.sql has been run.
 * It detects the optional provider columns at runtime and adapts, and every
 * DB step fails gracefully (returns null) instead of throwing a fatal 500.
 */

/** POST application/x-www-form-urlencoded, return decoded JSON as an array. */
function dabil_http_post(string $url, array $fields): array
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query($fields),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_HTTPHEADER     => ['Accept: application/json'],
    ]);
    $res = curl_exec($ch);
    curl_close($ch);
    return is_string($res) ? (json_decode($res, true) ?: []) : [];
}

/** GET a resource with a Bearer token, return decoded JSON as an array. */
function dabil_http_get(string $url, string $bearer): array
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $bearer, 'Accept: application/json'],
    ]);
    $res = curl_exec($ch);
    curl_close($ch);
    return is_string($res) ? (json_decode($res, true) ?: []) : [];
}

/** True if the optional OAuth columns exist on the users table. */
function dabil_users_has_oauth_columns(mysqli $conn): bool
{
    $res = @$conn->query("SHOW COLUMNS FROM `users` LIKE 'auth_provider'");
    return $res instanceof mysqli_result && $res->num_rows > 0;
}

/**
 * Find an existing customer by email, or create one from the social profile.
 * Returns the user row (assoc), or null on a hard failure.
 *
 * Account linking: we match on the verified email. A user who first signed up
 * with email/password can therefore also sign in with Google on the same email.
 */
function dabil_find_or_create_customer(
    mysqli $conn, string $email, string $name,
    string $providerUid, ?string $avatar, string $provider = 'google'
): ?array {
    $hasCols = dabil_users_has_oauth_columns($conn);

    // 1. Existing customer with this email?
    $stmt = $conn->prepare(
        "SELECT id, name, email, role, status
         FROM users
         WHERE email = ? AND role = 'customer'
         LIMIT 1"
    );
    if (!$stmt) {
        return null;
    }
    $stmt->bind_param('s', $email);
    $stmt->execute();
    $user = $stmt->get_result()->fetch_assoc();

    if ($user) {
        // Best-effort backfill. Never fatal: guard the prepare().
        if ($hasCols) {
            $up = $conn->prepare(
                "UPDATE users
                    SET provider_uid   = COALESCE(NULLIF(provider_uid, ''), ?),
                        auth_provider  = IF(auth_provider = 'local', ?, auth_provider),
                        email_verified = 1,
                        avatar         = COALESCE(avatar, ?)
                  WHERE id = ?"
            );
            if ($up) {
                $up->bind_param('sssi', $providerUid, $provider, $avatar, $user['id']);
                @$up->execute();
            }
        } elseif ($avatar) {
            $up = $conn->prepare("UPDATE users SET avatar = COALESCE(avatar, ?) WHERE id = ?");
            if ($up) {
                $up->bind_param('si', $avatar, $user['id']);
                @$up->execute();
            }
        }
        return $user;
    }

    // 2. Create a new customer. Random password hash => no password login.
    $randomHash = password_hash(bin2hex(random_bytes(32)), PASSWORD_DEFAULT);

    if ($hasCols) {
        $ins = $conn->prepare(
            "INSERT INTO users (name, email, password, role, status, avatar, auth_provider, provider_uid, email_verified)
             VALUES (?, ?, ?, 'customer', 1, ?, ?, ?, 1)"
        );
        if (!$ins) {
            return null;
        }
        $ins->bind_param('ssssss', $name, $email, $randomHash, $avatar, $provider, $providerUid);
    } else {
        // Migration not run yet — create using base columns only.
        $ins = $conn->prepare(
            "INSERT INTO users (name, email, password, role, status, avatar)
             VALUES (?, ?, ?, 'customer', 1, ?)"
        );
        if (!$ins) {
            return null;
        }
        $ins->bind_param('ssss', $name, $email, $randomHash, $avatar);
    }

    if (!$ins->execute()) {
        return null;
    }

    return [
        'id'     => $ins->insert_id,
        'name'   => $name,
        'email'  => $email,
        'role'   => 'customer',
        'status' => 1,
    ];
}

/** Start the customer session + returning cookie. Identical to login.php. */
function dabil_start_customer_session(array $user): void
{
    session_regenerate_id(true);
    $_SESSION['user_id']    = (int) $user['id'];
    $_SESSION['user_name']  = $user['name'];
    $_SESSION['user_email'] = $user['email'];
    $_SESSION['role']       = $user['role'];

    unset($_SESSION['login_error'], $_SESSION['login_redirect']);

    setcookie('dabil_returning', '1', [
        'expires'  => time() + 60 * 60 * 24 * 365,
        'path'     => '/',
        'secure'   => !empty($_SERVER['HTTPS']),
        'httponly' => true,
        'samesite' => 'Lax',
    ]);
}

/** Only allow relative same-site redirect targets (mirrors login.php). */
function dabil_safe_redirect(string $path): string
{
    $path = trim($path);
    if ($path === '') {
        return 'dashboard.php';
    }
    if (preg_match('#^([a-z][a-z0-9+.-]*:)?//#i', $path) || str_starts_with($path, '\\')) {
        return 'dashboard.php';
    }
    return $path;
}
