<?php
/**
 * get_register.php (PDO) - FINAL + reCAPTCHA
 * ✅ يمنع تكرار البريد من جدول users فقط
 * ✅ يمنع التسجيلات الوهمية عبر Google reCAPTCHA (Server-side verify + fallback recaptcha.net)
 * ✅ ينشئ حساب غير مفعل is_active=0
 * ✅ يولّد رقم حساب فريد account_number يبدأ بـ 42 (6 أرقام مبدئياً) + توسعة تلقائية
 * ✅ يولّد username فريد مثل eazy_hG8789 + توسعة تلقائية لطول الجزء العشوائي
 * ✅ لا يرسل البريد من هنا إطلاقاً
 * ✅ يعتمد على email_request.php لإرسال/تخزين كود التفعيل (LIB mode)
 *
 * الواجهة (register.php):
 * - أرسل: recaptcha_token (أو g_recaptcha_response)
 * - مثال JSON: { "email":"...", "password":"...", "recaptcha_token":"TOKEN" }
 */

$frontendOrigin = 'https://eazzybit.com';
$reqOrigin = $_SERVER['HTTP_ORIGIN'] ?? '';
if ($reqOrigin === $frontendOrigin) {
  header("Access-Control-Allow-Origin: {$frontendOrigin}");
  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");

// وضع تطوير
$DEBUG_MODE = true;
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;
}

/* ================= أدوات مساعدة ================= */
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);
}

/* ================= reCAPTCHA (Server-side verify) ================= */

/**
 * يتحقق من reCAPTCHA (يدعم v2/v3)
 * - يحاول google.com أولاً ثم recaptcha.net كـ fallback
 * - في v2: يكفي success=true
 * - في v3: يمكن فحص score إذا كان موجوداً (اختياري عبر RECAPTCHA_MIN_SCORE)
 */
function verify_recaptcha(string $token, string $remoteIp = ''): array {
  if (!defined('RECAPTCHA_SECRET') || !RECAPTCHA_SECRET) {
    return ['ok' => false, 'reason' => 'RECAPTCHA_SECRET_NOT_SET'];
  }
  if ($token === '') {
    return ['ok' => false, 'reason' => 'EMPTY_TOKEN'];
  }

  $endpoints = [
    'https://www.google.com/recaptcha/api/siteverify',
    'https://www.recaptcha.net/recaptcha/api/siteverify',
  ];

  $post = [
    'secret'   => RECAPTCHA_SECRET,
    'response' => $token,
  ];
  if ($remoteIp !== '') $post['remoteip'] = $remoteIp;

  $lastJson = null;

  foreach ($endpoints as $url) {
    $respRaw = null;

    if (function_exists('curl_init')) {
      $ch = curl_init($url);
      curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($post),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 8,
        CURLOPT_TIMEOUT => 15,
      ]);
      $respRaw = curl_exec($ch);
      curl_close($ch);
    } else {
      $context = stream_context_create([
        'http' => [
          'method'  => 'POST',
          'header'  => "Content-Type: application/x-www-form-urlencoded\r\n",
          'content' => http_build_query($post),
          'timeout' => 15,
        ]
      ]);
      $respRaw = @file_get_contents($url, false, $context);
    }

    if (!$respRaw) {
      continue;
    }

    $json = json_decode($respRaw, true);
    if (!is_array($json)) {
      continue;
    }

    $lastJson = $json;

    $success = !empty($json['success']);
    if (!$success) {
      return ['ok' => false, 'reason' => 'VERIFY_NOT_SUCCESS', 'errors' => $json['error-codes'] ?? []];
    }

    if (isset($json['score']) && defined('RECAPTCHA_MIN_SCORE')) {
      $min = (float)RECAPTCHA_MIN_SCORE;
      $score = (float)$json['score'];
      if ($score < $min) {
        return ['ok' => false, 'reason' => 'LOW_SCORE', 'score' => $score];
      }
    }

    if (defined('RECAPTCHA_EXPECTED_ACTION') && isset($json['action'])) {
      $expected = (string)RECAPTCHA_EXPECTED_ACTION;
      $action = (string)$json['action'];
      if ($expected !== '' && $action !== '' && $action !== $expected) {
        return ['ok' => false, 'reason' => 'ACTION_MISMATCH', 'action' => $action];
      }
    }

    return ['ok' => true, 'data' => $json, 'provider' => $url];
  }

  $extra = ['ok' => false, 'reason' => 'VERIFY_REQUEST_FAILED'];
  if (is_array($lastJson)) $extra['last'] = $lastJson;
  return $extra;
}

/* ================= توليد account_number (42 + توسعة) ================= */

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("تعذّر توليد رقم حساب فريد. حاول لاحقاً.");
}

/* ================= توليد username (eazy_XXXX + توسعة) ================= */

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_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("تعذّر توليد اسم مستخدم فريد. حاول لاحقاً.");
}

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

try {
  $input = read_json_input();

  $email    = strtolower(trim((string)($input['email'] ?? '')));
  $password = trim((string)($input['password'] ?? ''));

  // ✅ reCAPTCHA token من الواجهة
  $recaptchaToken =
    trim((string)($input['recaptcha_token'] ?? '')) ?:
    trim((string)($input['g_recaptcha_response'] ?? '')) ?:
    trim((string)($input['g-recaptcha-response'] ?? '')) ?:
    trim((string)($input['g-recaptcha-response'] ?? ''));

  // ✅ لا نطلب الاسم هنا
  $name = '';

  if ($email === '' || $password === '') {
    respond(false, 'بعض الحقول ناقصة', [], 400);
  }
  if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    respond(false, 'البريد الإلكتروني غير صالح', [], 400);
  }
  if (strlen($password) < 6) {
    respond(false, 'كلمة المرور يجب أن تكون 6 أحرف على الأقل', [], 400);
  }

  // ✅ reCAPTCHA إلزامي
  if ($recaptchaToken === '') {
    respond(false, 'التحقق مطلوب. أعد المحاولة.', ['captcha' => 'required'], 403);
  }

  $remoteIp = $_SERVER['REMOTE_ADDR'] ?? '';
  $cap = verify_recaptcha($recaptchaToken, $remoteIp);
  if (!$cap['ok']) {
    $extra = ['captcha' => 'failed'];

    if ($DEBUG_MODE) {
      $extra['captcha_reason'] = $cap['reason'] ?? 'unknown';
      if (isset($cap['score']))  $extra['captcha_score']  = $cap['score'];
      if (isset($cap['errors'])) $extra['captcha_errors'] = $cap['errors'];
      if (isset($cap['action'])) $extra['captcha_action'] = $cap['action'];
    }

    if (($cap['reason'] ?? '') === 'VERIFY_REQUEST_FAILED') {
      respond(false, 'تعذّر التحقق مؤقتاً. أعد المحاولة بعد قليل.', $extra, 503);
    }

    respond(false, 'فشل التحقق. حاول مرة أخرى.', $extra, 403);
  }

  // ✅ التحقق من users فقط
  $chk = $conn->prepare("SELECT id, is_active FROM users WHERE email = ? LIMIT 1");
  $chk->execute([$email]);
  $existing = $chk->fetch(PDO::FETCH_ASSOC);
  if ($existing) {
    respond(false, 'البريد مسجل مسبقاً. استخدم تسجيل الدخول.', [
      'exists'    => true,
      'is_active' => (int)$existing['is_active']
    ], 409);
  }

  $conn->beginTransaction();

  // ✅ توليد account_number + username
  $accountNumber = generate_unique_account_number($conn, 6, 120);
  $username      = generate_unique_username($conn, 'eazy_', 6, 200);

  // إنشاء حساب جديد غير مفعل
  $ins = $conn->prepare("
    INSERT INTO users (name, email, username, account_number, password, is_active, created_at)
    VALUES (?, ?, ?, ?, ?, 0, NOW())
  ");
  $ins->execute([
    $name,
    $email,
    $username,
    $accountNumber,
    password_hash($password, PASSWORD_DEFAULT)
  ]);

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

  /**
   * ✅ إرسال/تخزين كود التفعيل عبر email_request.php فقط (LIB mode)
   * ملاحظة: عدّل المسار إذا كان email_request.php في مكان مختلف.
   */
  if (!defined('YC_EMAIL_REQUEST_LIB')) define('YC_EMAIL_REQUEST_LIB', true);
  require_once __DIR__ . '/email_request.php';

  if (!function_exists('yc_email_request_send_code')) {
    $conn->rollBack();
    respond(false, 'تعذّر تحميل مكتبة إرسال البريد (email_request.php).', [], 500);
  }

  // عند التسجيل: لا حاجة لـ Rate limit عادةً
  $r = yc_email_request_send_code($conn, $userId, $email, $name, 60, false);

  if (empty($r['success'])) {
    $conn->rollBack();
    $status = (int)($r['status'] ?? 500);
    $msg    = (string)($r['message'] ?? 'تعذّر إرسال كود التفعيل.');
    $extra  = (array)($r['extra'] ?? []);
    respond(false, $msg, $extra, $status);
  }

  $conn->commit();

  $extra = (array)($r['extra'] ?? []);

  respond(true, (string)$r['message'], [
    'user_id'        => $userId,
    'email'          => $email,
    'username'       => $username,
    'account_number' => $accountNumber,
    'is_active'      => 0,
    'expires_at'     => $extra['expires_at'] ?? null,
    'ttl'            => $extra['ttl'] ?? 60
  ]);

} catch (PDOException $e) {
  if ($conn instanceof PDO && $conn->inTransaction()) $conn->rollBack();

  if (($e->getCode() ?? '') === '23000') {
    $msg = 'تعذر تنفيذ العملية (تكرار بيانات).';
    if (isset($email) && $email !== '') {
      $stmt = $conn->prepare("SELECT is_active FROM users WHERE email = ? LIMIT 1");
      $stmt->execute([$email]);
      $u = $stmt->fetch(PDO::FETCH_ASSOC);

      if ($u) {
        respond(false, 'البريد مسجل مسبقاً. استخدم تسجيل الدخول.', [
          'exists'    => true,
          'is_active' => isset($u['is_active']) ? (int)$u['is_active'] : 0
        ], 409);
      }
    }
    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 && $conn->inTransaction()) $conn->rollBack();
  log_error($e);
  $msg = 'خطأ في الخادم';
  if ($DEBUG_MODE) $msg .= ' - ' . $e->getMessage();
  respond(false, $msg, [], 500);
}
