<?php

declare(strict_types=1);

require_once "../db.php";
require_once "./customer_auth_common.php";

error_reporting(E_ERROR | E_PARSE);
ini_set("display_errors", "0");

if (($_SERVER["REQUEST_METHOD"] ?? "") !== "POST") {
    customerAuthJsonResponse(405, [
        "success" => false,
        "message" => "Method not allowed",
    ]);
}

$input = customerAuthReadJsonInput();
$idToken = customerAuthGetInputValue($input, "idToken", "id_token");

if ($idToken === "") {
    customerAuthJsonResponse(422, [
        "success" => false,
        "message" => "Google ID token is required.",
    ]);
}

$expectedClientId = trim((string) (getenv("GOOGLE_CLIENT_ID") ?: ""));
if ($expectedClientId === "") {
    customerAuthJsonResponse(503, [
        "success" => false,
        "message" => "Google login is not configured on the server.",
    ]);
}

$tokenInfoUrl = "https://oauth2.googleapis.com/tokeninfo?id_token=" . urlencode($idToken);
$httpOptions = [
    "http" => [
        "method" => "GET",
        "timeout" => 8,
        "ignore_errors" => true,
    ],
];
$context = stream_context_create($httpOptions);
$rawResponse = @file_get_contents($tokenInfoUrl, false, $context);

if (!is_string($rawResponse) || $rawResponse === "") {
    customerAuthJsonResponse(401, [
        "success" => false,
        "message" => "Unable to verify Google token.",
    ]);
}

$tokenData = json_decode($rawResponse, true);
if (!is_array($tokenData)) {
    customerAuthJsonResponse(401, [
        "success" => false,
        "message" => "Invalid Google token payload.",
    ]);
}

$audience = trim((string) ($tokenData["aud"] ?? ""));
$email = strtolower(trim((string) ($tokenData["email"] ?? "")));
$name = trim((string) ($tokenData["name"] ?? ""));
$emailVerified = (string) ($tokenData["email_verified"] ?? "false");

if ($audience !== $expectedClientId) {
    customerAuthJsonResponse(401, [
        "success" => false,
        "message" => "Google token audience mismatch.",
    ]);
}

if (!filter_var($email, FILTER_VALIDATE_EMAIL) || $emailVerified !== "true") {
    customerAuthJsonResponse(401, [
        "success" => false,
        "message" => "Google account email is not verified.",
    ]);
}

if ($name === "") {
    $name = strstr($email, "@", true) ?: "User";
}

$userStmt = $conn->prepare("SELECT id, name, role FROM users WHERE email = ? LIMIT 1");
if (!$userStmt) {
    customerAuthJsonResponse(500, [
        "success" => false,
        "message" => "Failed to prepare user lookup.",
    ]);
}

$userStmt->bind_param("s", $email);
$userStmt->execute();
$userResult = $userStmt->get_result();
$user = $userResult ? $userResult->fetch_assoc() : null;
$userStmt->close();

if ($user) {
    $userId = (int) $user["id"];
    $userName = trim((string) ($user["name"] ?? ""));
    $userRole = (string) ($user["role"] ?? "user");

    if ($userName === "" && $name !== "") {
        $updateNameStmt = $conn->prepare("UPDATE users SET name = ? WHERE id = ?");
        if ($updateNameStmt) {
            $updateNameStmt->bind_param("si", $name, $userId);
            $updateNameStmt->execute();
            $updateNameStmt->close();
            $userName = $name;
        }
    }
} else {
    $randomPassword = bin2hex(random_bytes(16));
    $passwordHash = password_hash($randomPassword, PASSWORD_BCRYPT);
    $userRole = "user";

    $createStmt = $conn->prepare(
        "INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, ?)"
    );
    if (!$createStmt) {
        customerAuthJsonResponse(500, [
            "success" => false,
            "message" => "Failed to create account.",
        ]);
    }

    $createStmt->bind_param("ssss", $name, $email, $passwordHash, $userRole);
    if (!$createStmt->execute()) {
        $error = $createStmt->error;
        $createStmt->close();
        customerAuthJsonResponse(500, [
            "success" => false,
            "message" => "Failed to create account.",
            "error" => $error,
        ]);
    }

    $userId = (int) $conn->insert_id;
    $userName = $name;
    $createStmt->close();
}

try {
    $session = customerAuthCreateSession($conn, $userId);
} catch (RuntimeException $exception) {
    customerAuthJsonResponse(500, [
        "success" => false,
        "message" => "Unable to create login session.",
    ]);
}

customerAuthJsonResponse(200, [
    "success" => true,
    "message" => "Authentication successful.",
    "token" => $session["token"],
    "expiresAt" => $session["expiresAt"],
    "expiresInSeconds" => $session["expiresInSeconds"],
    "user" => [
        "id" => $userId,
        "name" => $userName,
        "email" => $email,
        "role" => $userRole ?? "user",
    ],
]);

