<?php
session_start();

/**
 * google_auth.php (PDO) - Google Sign-In via ID Token (GIS)
 * ✅ يستقبل id_token من الواجهة
 * ✅ يتحقق من التوكن عبر tokeninfo (aud/iss/exp/email_verified)
 * ✅ ينشئ مستخدم جديد أو يربط المستخدم الحالي بحساب Google
 * ✅ يفعّل الحساب (is_active=1) لأن بريد Google موثّق
 * ✅ ينشئ Device Token (Cookie yc_device) + user_token + سجلات:
 *    user_devices / user_sessions / user_logins
 * ✅ يرجّع: user_id + email + device + user_token
 */

$allowedOrigins = [
  'https://eazzybit.com',
  // 'https://www.eazzybit.com', // فعّلها إذا تستخدم www
];

/* ================== CORS ================== */
$reqOrigin = $_SERVER['HTTP_ORIGIN'] ?? '';
if ($reqOrigin && in_array($reqOrigin, $allowedOrigins, true)) {
  header("Access-Control-Allow-Origin: {$reqOrigin}");
  header("Vary: Origin");
  header("Access-Control-Allow-Credentials: true");
}
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Max-Age: 600");
header("Content-Type: application/json; charset=UTF-8");
/* =================================================== */

// اجعلها false في الإنتاج
$DEBUG_MODE = false;
if ($DEBUG_MODE) { ini_set('display_errors', 1); error_reporting(E_ALL); }
else { ini_set('display_errors', 0); error_reporting(0); }

// Preflight
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
  http_response_code(204);
  exit;
}

// POST فقط
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
  http_response_code(405);
  echo json_encode(['success' => false, 'message' => 'طريقة الطلب غير مسموحة. استخدم POST فقط.'], JSON_UNESCAPED_UNICODE);
  exit;
}

/* ================= Helpers ================= */
function respond(bool $success, string $message, array $extra = [], int $status = 200): void {
  http_response_code($status);
  echo json_encode(
    array_merge(['success' => $success, 'message' => $message], $extra),
    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
  );
  exit;
}

function read_json_input(): array {
  $raw = file_get_contents('php://input') ?: '';
  $data = json_decode($raw, true);
  if (!is_array($data)) respond(false, 'البيانات المرسلة غير صالحة', [], 400);
  return $data;
}

function log_error(Throwable $e): void {
  $dir = __DIR__ . '/../../logs';
  if (!is_dir($dir)) @mkdir($dir, 0755, true);
  $file = $dir . '/api_errors_' . date('Y-m-d') . '.log';
  $line = "[" . date('Y-m-d H:i:s') . "] " . $e->getMessage() . " | " . $e->getFile() . ":" . $e->getLine() . PHP_EOL;
  @file_put_contents($file, $line, FILE_APPEND | LOCK_EX);
}

function safe_begin(PDO $conn): void { if (!$conn->inTransaction()) $conn->beginTransaction(); }
function safe_rollback(PDO $conn): void { if ($conn->inTransaction()) $conn->rollBack(); }
function safe_commit(PDO $conn): void { if ($conn->inTransaction()) $conn->commit(); }

/**
 * Device cookie (ثابت لكل جهاز) - نفس email_confirm.php
 */
function getOrCreateDeviceToken(): string {
  $cookieName = 'yc_device';
  if (!empty($_COOKIE[$cookieName])) return (string)$_COOKIE[$cookieName];

  $token = hash('sha256', random_bytes(32));

  $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
  $options = [
    'expires'  => time() + (3600 * 24 * 365 * 2),
    'path'     => '/',
    // 'domain' => '.eazzybit.com', // فعّلها فقط لو تحتاج مشاركة بين subdomains
    'secure'   => $isHttps ? true : false, // في الإنتاج الأفضل true
    'httponly' => true,
    'samesite' => 'Lax',
  ];

  @setcookie($cookieName, $token, $options);
  return $token;
}

function http_get(string $url, int $timeout = 10): ?string {
  if (function_exists('curl_init')) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_CONNECTTIMEOUT => 6,
      CURLOPT_TIMEOUT => $timeout,
      CURLOPT_SSL_VERIFYPEER => true,
      CURLOPT_SSL_VERIFYHOST => 2,
    ]);
    $resp = curl_exec($ch);
    $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($http >= 200 && $http < 300 && $resp) return $resp;
    return null;
  }

  $context = stream_context_create([
    'http' => ['method' => 'GET', 'timeout' => $timeout],
    'ssl'  => ['verify_peer' => true, 'verify_peer_name' => true],
  ]);
  $resp = @file_get_contents($url, false, $context);
  return $resp ?: null;
}

/**
 * ✅ تحقق Google ID Token عبر tokeninfo
 */
function verify_google_id_token(string $idToken, string $expectedClientId): array {
  $url = 'https://oauth2.googleapis.com/tokeninfo?id_token=' . urlencode($idToken);
  $raw = http_get($url, 12);
  if (!$raw) return ['ok' => false, 'reason' => 'TOKENINFO_REQUEST_FAILED'];

  $payload = json_decode($raw, true);
  if (!is_array($payload)) return ['ok' => false, 'reason' => 'TOKENINFO_BAD_RESPONSE'];

  $aud  = (string)($payload['aud'] ?? '');
  $iss  = (string)($payload['iss'] ?? '');
  $sub  = (string)($payload['sub'] ?? '');
  $email = (string)($payload['email'] ?? '');
  $emailVerified = $payload['email_verified'] ?? null;
  $exp  = (int)($payload['exp'] ?? 0);

  if ($aud !== $expectedClientId) return ['ok' => false, 'reason' => 'AUD_MISMATCH'];
  if ($iss !== 'accounts.google.com' && $iss !== 'https://accounts.google.com') return ['ok' => false, 'reason' => 'ISS_MISMATCH'];
  if ($exp > 0 && $exp < time()) return ['ok' => false, 'reason' => 'TOKEN_EXPIRED'];
  if ($sub === '' || $email === '') return ['ok' => false, 'reason' => 'MISSING_SUB_OR_EMAIL'];

  $isVerified = ($emailVerified === true || $emailVerified === 'true' || $emailVerified === 1 || $emailVerified === '1');
  if (!$isVerified) return ['ok' => false, 'reason' => 'EMAIL_NOT_VERIFIED'];

  return ['ok' => true, 'data' => $payload];
}

/* ================= توليد user_token + username + account_number ================= */

function gen_user_token(): string {
  // متوافق مع email_confirm (64 hex)
  return hash('sha256', random_bytes(32));
}

function random_alpha_num(int $len): string {
  $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  $out = '';
  for ($i = 0; $i < $len; $i++) $out .= $chars[random_int(0, strlen($chars) - 1)];
  return $out;
}

function generate_account_candidate(int $length): string {
  if ($length < 3) $length = 3;
  $prefix = "42";
  $remain = $length - strlen($prefix);
  if ($remain < 1) $remain = 1;

  $max = (10 ** $remain) - 1;
  $rand = str_pad((string) random_int(0, $max), $remain, "0", STR_PAD_LEFT);
  return $prefix . $rand;
}

function generate_unique_account_number(PDO $conn, int $startLen = 6, int $triesPerLen = 120): string {
  $len = max(6, $startLen);

  for ($grow = 0; $grow < 10; $grow++) {
    for ($i = 0; $i < $triesPerLen; $i++) {
      $candidate = generate_account_candidate($len);
      $chk = $conn->prepare("SELECT id FROM users WHERE account_number = ? LIMIT 1");
      $chk->execute([$candidate]);
      if (!$chk->fetch(PDO::FETCH_ASSOC)) return $candidate;
    }
    $len++;
  }

  throw new RuntimeException("تعذّر توليد رقم حساب فريد. حاول لاحقاً.");
}

function generate_unique_username(PDO $conn, string $prefix = 'eazy_', int $startRandLen = 6, int $triesPerLen = 200): string {
  $randLen = max(4, $startRandLen);

  for ($grow = 0; $grow < 10; $grow++) {
    for ($i = 0; $i < $triesPerLen; $i++) {
      $candidate = $prefix . random_alpha_num($randLen);
      $chk = $conn->prepare("SELECT id FROM users WHERE username = ? LIMIT 1");
      $chk->execute([$candidate]);
      if (!$chk->fetch(PDO::FETCH_ASSOC)) return $candidate;
    }
    $randLen++;
  }

  throw new RuntimeException("تعذّر توليد اسم مستخدم فريد. حاول لاحقاً.");
}

function current_db_name(PDO $conn): string {
  try { $db = $conn->query("SELECT DATABASE()")->fetchColumn(); return $db ? (string)$db : ''; }
  catch (Throwable $e) { return ''; }
}

function column_exists(PDO $conn, string $table, string $column): bool {
  $db = current_db_name($conn);
  if ($db === '') return false;

  $st = $conn->prepare("
    SELECT COUNT(*) FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?
  ");
  $st->execute([$db, $table, $column]);
  return ((int)$st->fetchColumn()) > 0;
}

function ensure_user_tokens_table(PDO $conn): void {
  $conn->exec("
    CREATE TABLE IF NOT EXISTS user_tokens (
      id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT UNSIGNED NOT NULL,
      token VARCHAR(128) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      UNIQUE KEY uq_token (token),
      KEY idx_user_id (user_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  ");
}

function store_user_token(PDO $conn, int $userId, string $token): void {
  if (column_exists($conn, 'users', 'user_token')) {
    $st = $conn->prepare("UPDATE users SET user_token = ? WHERE id = ? LIMIT 1");
    $st->execute([$token, $userId]);
    return;
  }
  ensure_user_tokens_table($conn);
  $st = $conn->prepare("INSERT INTO user_tokens (user_id, token) VALUES (?, ?)");
  $st->execute([$userId, $token]);
}

function make_dummy_password_hash(): string {
  return password_hash(bin2hex(random_bytes(24)), PASSWORD_DEFAULT);
}

/* ================= التشغيل ================= */

// ضع Client ID الخاص بك هنا
$GOOGLE_CLIENT_ID = "450126618572-4lc0g55ti5jjlrurkt4ahbqiqhp0q62r.apps.googleusercontent.com";

// اتصال قاعدة البيانات من config.php
require_once __DIR__ . '/../config.php';
if (!isset($conn) || !($conn instanceof PDO)) {
  respond(false, 'اتصال قاعدة البيانات غير متوفر.', [], 500);
}

try {
  $input = read_json_input();
  $idToken = trim((string)($input['id_token'] ?? ''));

  if ($idToken === '') respond(false, 'حقل id_token مطلوب', [], 400);

  // 1) تحقق التوكن
  $v = verify_google_id_token($idToken, $GOOGLE_CLIENT_ID);
  if (!$v['ok']) {
    $extra = ['google' => 'invalid_token'];
    if ($DEBUG_MODE) $extra['google_reason'] = $v['reason'] ?? 'unknown';
    respond(false, 'فشل التحقق من Google. أعد المحاولة.', $extra, 401);
  }

  $p = $v['data'];

  $googleSub   = (string)($p['sub'] ?? '');
  $email       = strtolower(trim((string)($p['email'] ?? '')));
  $name        = trim((string)($p['name'] ?? ''));
  $picture     = trim((string)($p['picture'] ?? ''));

  // 2) ابحث/أنشئ المستخدم
  safe_begin($conn);

  $user = null;

  $hasOauthProvider = column_exists($conn, 'users', 'oauth_provider');
  $hasOauthSub      = column_exists($conn, 'users', 'oauth_sub');

  if ($hasOauthProvider && $hasOauthSub) {
    $st = $conn->prepare("SELECT * FROM users WHERE oauth_provider='google' AND oauth_sub=? LIMIT 1");
    $st->execute([$googleSub]);
    $user = $st->fetch(PDO::FETCH_ASSOC);
  }

  if (!$user) {
    $st = $conn->prepare("SELECT * FROM users WHERE email=? LIMIT 1");
    $st->execute([$email]);
    $user = $st->fetch(PDO::FETCH_ASSOC);
  }

  if ($user) {
    $userId = (int)($user['id'] ?? 0);
    if ($userId <= 0) {
      safe_rollback($conn);
      respond(false, 'بيانات المستخدم غير صالحة.', [], 500);
    }

    // اربط المستخدم بـ Google إن أمكن
    if ($hasOauthProvider && $hasOauthSub) {
      $currentProvider = (string)($user['oauth_provider'] ?? '');
      $currentSub      = (string)($user['oauth_sub'] ?? '');

      if ($currentProvider === 'google' && $currentSub !== '' && $currentSub !== $googleSub) {
        safe_rollback($conn);
        respond(false, 'هذا البريد مرتبط بحساب Google مختلف.', ['conflict' => true], 409);
      }

      if ($currentProvider !== '' && $currentProvider !== 'google' && $currentSub !== '') {
        safe_rollback($conn);
        respond(false, 'هذا البريد مرتبط بمزود تسجيل دخول آخر.', ['conflict' => true], 409);
      }

      $set = [];
      $vals = [];

      $set[] = "oauth_provider='google'";
      $set[] = "oauth_sub=?";
      $vals[] = $googleSub;

      if (column_exists($conn, 'users', 'oauth_email')) {
        $set[] = "oauth_email=?";
        $vals[] = $email;
      }
      if (column_exists($conn, 'users', 'oauth_email_verified')) {
        $set[] = "oauth_email_verified=1";
      }
      if ($name !== '' && column_exists($conn, 'users', 'oauth_name')) {
        $set[] = "oauth_name=?";
        $vals[] = $name;
      }
      if ($picture !== '' && column_exists($conn, 'users', 'avatar_url')) {
        $set[] = "avatar_url=?";
        $vals[] = $picture;
      }
      if (column_exists($conn, 'users', 'oauth_linked_at')) {
        $set[] = "oauth_linked_at=NOW()";
      }

      if (column_exists($conn, 'users', 'is_active')) {
        $set[] = "is_active=1";
      }

      $sql = "UPDATE users SET " . implode(", ", $set) . " WHERE id=? LIMIT 1";
      $vals[] = $userId;
      $up = $conn->prepare($sql);
      $up->execute($vals);

    } else {
      if (column_exists($conn, 'users', 'is_active')) {
        $up = $conn->prepare("UPDATE users SET is_active=1 WHERE id=? LIMIT 1");
        $up->execute([$userId]);
      }
    }

  } else {
    // إنشاء مستخدم جديد
    $username = null;
    $accountNumber = null;

    if (column_exists($conn, 'users', 'username')) {
      $username = generate_unique_username($conn, 'eazy_', 6, 200);
    }
    if (column_exists($conn, 'users', 'account_number')) {
      $accountNumber = generate_unique_account_number($conn, 6, 120);
    }

    $cols = [];
    $ph   = [];
    $vals = [];

    if (column_exists($conn, 'users', 'name')) {
      $cols[] = "name"; $ph[] = "?"; $vals[] = "";
    }

    $cols[] = "email"; $ph[] = "?"; $vals[] = $email;

    if ($username !== null) {
      $cols[] = "username"; $ph[] = "?"; $vals[] = $username;
    }
    if ($accountNumber !== null) {
      $cols[] = "account_number"; $ph[] = "?"; $vals[] = $accountNumber;
    }

    if (column_exists($conn, 'users', 'password_hash')) {
      $cols[] = "password_hash"; $ph[] = "?"; $vals[] = make_dummy_password_hash();
    } elseif (column_exists($conn, 'users', 'password')) {
      $cols[] = "password"; $ph[] = "NULL";
    }

    if (column_exists($conn, 'users', 'is_active')) {
      $cols[] = "is_active"; $ph[] = "1";
    }

    if (column_exists($conn, 'users', 'created_at')) {
      $cols[] = "created_at"; $ph[] = "NOW()";
    }

    if ($hasOauthProvider) { $cols[] = "oauth_provider"; $ph[] = "'google'"; }
    if ($hasOauthSub)      { $cols[] = "oauth_sub";      $ph[] = "?"; $vals[] = $googleSub; }

    if (column_exists($conn, 'users', 'oauth_email')) {
      $cols[] = "oauth_email"; $ph[] = "?"; $vals[] = $email;
    }
    if (column_exists($conn, 'users', 'oauth_email_verified')) {
      $cols[] = "oauth_email_verified"; $ph[] = "1";
    }
    if ($name !== '' && column_exists($conn, 'users', 'oauth_name')) {
      $cols[] = "oauth_name"; $ph[] = "?"; $vals[] = $name;
    }
    if ($picture !== '' && column_exists($conn, 'users', 'avatar_url')) {
      $cols[] = "avatar_url"; $ph[] = "?"; $vals[] = $picture;
    }
    if (column_exists($conn, 'users', 'oauth_linked_at')) {
      $cols[] = "oauth_linked_at"; $ph[] = "NOW()";
    }

    $sql = "INSERT INTO users (" . implode(", ", $cols) . ") VALUES (" . implode(", ", $ph) . ")";
    $ins = $conn->prepare($sql);
    $ins->execute($vals);

    $userId = (int)$conn->lastInsertId();
    if ($userId <= 0) {
      safe_rollback($conn);
      respond(false, 'تعذّر إنشاء الحساب عبر Google.', [], 500);
    }
  }

  /* ================== ✅ Device + Sessions (مثل email_confirm.php) ================== */
  $device      = getOrCreateDeviceToken();          // token string
  $userToken   = gen_user_token();                  // token string
  $ip          = $_SERVER['REMOTE_ADDR'] ?? null;
  $ua          = $_SERVER['HTTP_USER_AGENT'] ?? '';
  $deviceName  = mb_substr($ua, 0, 150);
  $deviceType  = 'Web Browser';
  $deviceModel = 'Browser';

  // خزّن user_token حسب تصميم قاعدة بياناتك (users.user_token أو user_tokens table)
  store_user_token($conn, (int)$userId, $userToken);

  // user_devices upsert
  $d = $conn->prepare("
    INSERT INTO user_devices (user_id, device, device_name, device_type, device_model, created_at)
    VALUES (?, ?, ?, ?, ?, NOW())
    ON DUPLICATE KEY UPDATE
      user_id = VALUES(user_id),
      device_name = VALUES(device_name),
      device_type = VALUES(device_type),
      device_model = VALUES(device_model)
  ");
  $d->execute([(int)$userId, (string)$device, (string)$deviceName, (string)$deviceType, (string)$deviceModel]);

  // user_sessions insert
  $s = $conn->prepare("
    INSERT INTO user_sessions
      (user_id, device, user_token, ip_address, country, governorate, device_name, device_type, device_model, session_start, last_activity_at, session_end, is_online)
    VALUES
      (?, ?, ?, ?, NULL, NULL, ?, ?, ?, NOW(), NOW(), NULL, 1)
  ");
  $s->execute([(int)$userId, (string)$device, (string)$userToken, $ip, (string)$deviceName, (string)$deviceType, (string)$deviceModel]);

  // user_logins insert
  $l = $conn->prepare("
    INSERT INTO user_logins
      (user_id, ip_address, country, governorate, device_name, device_type, device_model, device, user_token, login_at)
    VALUES
      (?, ?, NULL, NULL, ?, ?, ?, ?, ?, NOW())
  ");
  $l->execute([(int)$userId, (string)$ip, (string)$deviceName, (string)$deviceType, (string)$deviceModel, (string)$device, (string)$userToken]);

  // Session (اختياري)
  $_SESSION['user_id'] = (int)$userId;

  safe_commit($conn);

  respond(true, 'تم تسجيل الدخول عبر Google بنجاح', [
    'user_id'        => (int)$userId,
    'user_token'     => (string)$userToken,
    'email'          => (string)$email,
    'device'         => (string)$device,
    'email_verified' => 1
  ]);

} catch (PDOException $e) {
  if ($conn instanceof PDO) safe_rollback($conn);

  if (($e->getCode() ?? '') === '23000') {
    $msg = 'تعذّر تنفيذ العملية (تكرار بيانات).';
    if ($DEBUG_MODE) $msg .= ' - ' . $e->getMessage();
    respond(false, $msg, ['exists' => true], 409);
  }

  log_error($e);
  $msg = 'خطأ في الخادم';
  if ($DEBUG_MODE) $msg .= ' - ' . $e->getMessage();
  respond(false, $msg, [], 500);

} catch (Throwable $e) {
  if ($conn instanceof PDO) safe_rollback($conn);
  log_error($e);
  $msg = 'خطأ في الخادم';
  if ($DEBUG_MODE) $msg .= ' - ' . $e->getMessage();
  respond(false, $msg, [], 500);
}
