:root{--bg:#f4f6fb;--card:#fff;--line:#e3e7ef;--text:#141a2b;--muted:#6b7385;--pri:#5b5ce6;--ok:#16a34a;--bad:#dc2626;--warn:#d97706}
*{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",sans-serif;background:var(--bg);color:var(--text)}
a{color:var(--pri);text-decoration:none}.muted{color:var(--muted)}.small{font-size:12px}.center{text-align:center}.mono{font-family:monospace}
.app{display:flex;min-height:100vh}.side{width:230px;background:#11152a;color:#cfd3e6;padding:18px;flex-shrink:0}
.logo{font-weight:800;font-size:20px;color:#fff;margin-bottom:20px}.side nav a{display:block;color:#cfd3e6;padding:10px 12px;border-radius:8px}.side nav a:hover{background:#1f2544;color:#fff}
.nav-h{font-size:11px;letter-spacing:2px;margin:16px 12px 6px;color:#7b82a8}.out{color:#f87171!important;margin-top:16px}
main{flex:1;min-width:0}.top{display:flex;align-items:center;gap:12px;padding:14px 20px;background:#fff;border-bottom:1px solid var(--line)}.top h1{font-size:18px;margin:0;flex:1}
.menu{display:none;border:0;background:none;font-size:22px}.chip{background:#eef0ff;color:var(--pri);padding:6px 12px;border-radius:20px;font-weight:700}
.content{padding:20px}.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px;margin-bottom:16px;overflow-x:auto}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:16px}.stat{background:#fff;border:1px solid var(--line);border-radius:14px;padding:16px}.stat span{color:var(--muted);font-size:13px}.stat b{display:block;font-size:22px;margin-top:6px}
input,select{width:100%;padding:12px;border:1px solid var(--line);border-radius:10px;font-size:15px;margin:4px 0 12px;background:#fff}
label{font-weight:600;font-size:14px;display:block;margin-top:6px}label b{color:var(--bad)}
.btn{background:var(--pri);color:#fff;border:0;padding:12px 18px;border-radius:10px;font-weight:700;cursor:pointer;font-size:15px;display:inline-block}.btn.full{width:100%;padding:16px;font-size:18px;margin-top:10px}
.btn.sm{padding:6px 10px;font-size:12px}.btn.ok{background:var(--ok)}.btn.bad{background:var(--bad)}input.sm{width:80px;padding:6px;margin:0;font-size:12px}
.row{display:flex;gap:8px;align-items:flex-start;margin-bottom:12px}.row input{margin:0}.inline{display:inline-flex;gap:4px;margin:2px}
table{width:100%;border-collapse:collapse;font-size:14px}th,td{text-align:left;padding:10px 8px;border-bottom:1px solid var(--line);vertical-align:top}th{color:var(--muted);font-size:12px;text-transform:uppercase}
.badge{padding:3px 9px;border-radius:20px;font-size:12px;font-weight:700;background:#eee}.b-active,.b-success,.b-approved{background:#dcfce7;color:var(--ok)}.b-pending{background:#fef3c7;color:var(--warn)}.b-suspended,.b-rejected,.b-expired{background:#fee2e2;color:var(--bad)}.b-admin{background:#eef0ff;color:var(--pri)}
.alert{padding:12px 14px;border-radius:10px;margin-bottom:14px}.alert.ok{background:#dcfce7;color:#14532d}.alert.err{background:#fee2e2;color:#7f1d1d}.alert.warn{background:#fef3c7;color:#78350f}
.tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}.tabs a{padding:8px 14px;border-radius:20px;background:#fff;border:1px solid var(--line);color:var(--text)}.tabs a.on{background:var(--pri);color:#fff}
.otp{font-size:18px;color:var(--ok)}.copy{border:0;background:none;cursor:pointer}pre{white-space:pre-wrap;font-size:13px}
body.auth{display:flex;justify-content:center;padding:20px}.auth-card{width:100%;max-width:440px}.auth-card h2{margin:0}
.in{display:flex;align-items:center;border:1px solid var(--line);border-radius:12px;padding:0 14px;margin:6px 0 16px;background:#fff}.in span{opacity:.6}.in input{border:0;margin:0;padding:16px 12px;outline:0}
.eye{border:0;background:none;cursor:pointer;opacity:.6}.chk{display:flex;gap:10px;align-items:center;font-weight:400}.chk input{width:20px;height:20px;margin:0}
@media(max-width:800px){.side{position:fixed;left:-240px;top:0;bottom:0;z-index:9;transition:.2s}.side.open{left:0}.menu{display:block}.content{padding:12px}}
<?php
require 'lib.php';
header('Content-Type: application/json');

$u = me();
if (!$u) {
  echo json_encode(['ok' => false, 'error' => 'Login required']);
  exit;
}

$act = $_GET['action'] ?? '';
$csrf = $_SERVER['HTTP_X_CSRF'] ?? '';
if ($csrf !== ($_SESSION['csrf'] ?? 'x')) {
  echo json_encode(['ok' => false, 'error' => 'Invalid CSRF token']);
  exit;
}

function detect_country_operator($number) {
  $clean = preg_replace('/[^0-9]/', '', (string)$number);
  $map = [
    '249' => ['country' => 'Sudan', 'flag' => '🇸🇩', 'operator' => 'Zamtel / Zain'],
    '237' => ['country' => 'Cameroon', 'flag' => '🇨🇲', 'operator' => 'MTN / Orange'],
    '225' => ['country' => 'Ivory Coast', 'flag' => '🇨🇮', 'operator' => 'Orange / MTN'],
    '234' => ['country' => 'Nigeria', 'flag' => '🇳🇬', 'operator' => 'MTN / Airtel'],
    '880' => ['country' => 'Bangladesh', 'flag' => '🇧🇩', 'operator' => 'Grameenphone / Robi'],
    '91'  => ['country' => 'India', 'flag' => '🇮🇳', 'operator' => 'Jio / Airtel'],
    '92'  => ['country' => 'Pakistan', 'flag' => '🇵🇰', 'operator' => 'Jazz / Zong'],
    '1'   => ['country' => 'United States', 'flag' => '🇺🇸', 'operator' => 'T-Mobile / AT&T'],
    '44'  => ['country' => 'United Kingdom', 'flag' => '🇬🇧', 'operator' => 'EE / Vodafone'],
    '254' => ['country' => 'Kenya', 'flag' => '🇰🇪', 'operator' => 'Safaricom'],
    '233' => ['country' => 'Ghana', 'flag' => '🇬🇭', 'operator' => 'MTN / Vodafone'],
    '62'  => ['country' => 'Indonesia', 'flag' => '🇮🇩', 'operator' => 'Telkomsel'],
    '63'  => ['country' => 'Philippines', 'flag' => '🇵🇭', 'operator' => 'Globe / Smart'],
    '84'  => ['country' => 'Vietnam', 'flag' => '🇻🇳', 'operator' => 'Viettel'],
    '20'  => ['country' => 'Egypt', 'flag' => '🇪🇬', 'operator' => 'Vodafone Egypt'],
    '212' => ['country' => 'Morocco', 'flag' => '🇲🇦', 'operator' => 'Maroc Telecom'],
    '27'  => ['country' => 'South Africa', 'flag' => '🇿🇦', 'operator' => 'Vodacom / MTN'],
  ];

  foreach ($map as $prefix => $data) {
    if (strpos($clean, $prefix) === 0) {
      return $data;
    }
  }

  return ['country' => 'Global', 'flag' => '🌐', 'operator' => 'Virtual Route'];
}

if ($act === 'getnum') {
  if ($u['status'] !== 'active') {
    echo json_encode(['ok' => false, 'error' => 'আপনার অ্যাকাউন্ট এখনো অ্যাক্টিভ করা হয়নি']);
    exit;
  }

  $range = trim($_POST['range'] ?? '');
  $national_format = !empty($_POST['national_format']);
  $remove_plus = !empty($_POST['remove_plus']);

  if ($range !== '' && !preg_match('/^[0-9Xx*]{1,20}$/', $range)) {
    echo json_encode(['ok' => false, 'error' => 'Range এ শুধু সংখ্যা ও X ব্যবহার করা যাবে']);
    exit;
  }

  $payload = [];
  if ($range !== '') $payload['range'] = $range;
  if ($national_format) $payload['national_format'] = 1;
  if ($remove_plus) $payload['remove_plus'] = 1;

  $r = mk('/getnum/number', count($payload) ? $payload : new stdClass());
  if (!$r['ok']) {
    echo json_encode($r);
    exit;
  }

  $d = $r['data'];
  $rid = (string)($d['request_id'] ?? $d['id'] ?? '');
  if ($rid === '') {
    echo json_encode(['ok' => false, 'error' => 'প্রোভাইডার থেকে সঠিক রিকোয়েস্ট আইডি পাওয়া যায়নি']);
    exit;
  }

  $num = (string)($d['number'] ?? $d['full_number'] ?? '-');
  $full_num = (string)($d['full_number'] ?? $d['number'] ?? $num);

  if ($remove_plus) {
    $num = ltrim($num, '+');
    $full_num = ltrim($full_num, '+');
  }

  db()->prepare('INSERT INTO number_requests(user_id,mk_request_id,number,full_number,num_range) VALUES(?,?,?,?,?)')
    ->execute([$u['id'], $rid, $num, $full_num, $range ?: null]);

  echo json_encode(['ok' => true]);
  exit;
}

if ($act === 'check') {
  $s = db()->prepare("SELECT * FROM number_requests WHERE user_id=? AND status='pending'");
  $s->execute([$u['id']]);
  $pendingRows = $s->fetchAll();

  if ($pendingRows) {
    $r = mk('/check/status', ['request_ids' => array_column($pendingRows, 'mk_request_id')]);
    if ($r['ok']) {
      $p = $r['data'];
      $list = isset($p['results']) ? $p['results'] : (isset($p['data']) ? $p['data'] : $p);
      $map = [];

      foreach ((array)$list as $k => $it) {
        if (!is_array($it)) continue;
        $id = (string)($it['request_id'] ?? $it['id'] ?? $k);
        $map[$id] = $it;
      }

      foreach ($pendingRows as $row) {
        $rid = (string)$row['mk_request_id'];
        $it = $map[$rid] ?? (count($pendingRows) === 1 && isset($list[0]) ? $list[0] : null);
        if (!$it) continue;

        $st = strtolower(trim((string)($it['status'] ?? 'pending')));
        $otp = $it['otp'] ?? $it['code'] ?? $it['otp_code'] ?? $it['sms_code'] ?? $it['pin'] ?? null;
        $sms = $it['sms'] ?? $it['message'] ?? $it['text'] ?? $it['content'] ?? null;

        // Auto extract OTP from SMS if separate OTP is missing
        if (!$otp && $sms && preg_match('/\b([0-9]{4,8})\b/', $sms, $matches)) {
          $otp = $matches[1];
        }

        $isSuccess = in_array($st, ['success', 'completed', 'received', 'delivered', 'finish', 'done']) || !empty($otp);
        $isExpired = in_array($st, ['expired', 'failed', 'lost', 'not_found', 'timeout']) || (strtotime($row['created_at']) < time() - 16 * 60);

        if ($isSuccess) {
          $pdo = db();
          $pdo->beginTransaction();
          $c = $pdo->prepare('SELECT credited FROM number_requests WHERE id=? FOR UPDATE');
          $c->execute([$row['id']]);
          if (!$c->fetchColumn()) {
            $pdo->prepare("UPDATE number_requests SET status='success', otp=?, sms=?, credited=1, reward=?, updated_at=NOW() WHERE id=?")
              ->execute([$otp ? (string)$otp : '—', $sms, $u['rate'], $row['id']]);
            $pdo->prepare('UPDATE users SET balance=balance+? WHERE id=?')
              ->execute([$u['rate'], $u['id']]);
          }
          $pdo->commit();
        } elseif ($isExpired) {
          db()->prepare("UPDATE number_requests SET status='expired', updated_at=NOW() WHERE id=?")
            ->execute([$row['id']]);
        }
      }
    }
  }

  // Fetch recent rows
  $s = db()->prepare('SELECT id, number, full_number, status, otp, sms, reward, created_at FROM number_requests WHERE user_id=? ORDER BY id DESC LIMIT 50');
  $s->execute([$u['id']]);
  $allRows = $s->fetchAll();

  // Attach detected country & operator
  foreach ($allRows as &$row) {
    $info = detect_country_operator($row['full_number'] ?: $row['number']);
    $row['country'] = $info['country'];
    $row['flag'] = $info['flag'];
    $row['operator'] = $info['operator'];
  }
  unset($row);

  // Stats calculation
  $stTotal = db()->prepare("SELECT COUNT(*) FROM number_requests WHERE user_id=? AND DATE(created_at) = CURDATE()");
  $stTotal->execute([$u['id']]);
  $todayTotal = (int)$stTotal->fetchColumn();

  $stSuccess = db()->prepare("SELECT COUNT(*) FROM number_requests WHERE user_id=? AND status='success' AND DATE(created_at) = CURDATE()");
  $stSuccess->execute([$u['id']]);
  $todaySuccess = (int)$stSuccess->fetchColumn();

  $stPending = db()->prepare("SELECT COUNT(*) FROM number_requests WHERE user_id=? AND status='pending'");
  $stPending->execute([$u['id']]);
  $livePending = (int)$stPending->fetchColumn();

  $stFailed = db()->prepare("SELECT COUNT(*) FROM number_requests WHERE user_id=? AND status IN ('expired','failed','lost') AND DATE(created_at) = CURDATE()");
  $stFailed->execute([$u['id']]);
  $todayFailed = (int)$stFailed->fetchColumn();

  // Balance
  $b = db()->prepare('SELECT balance FROM users WHERE id=?');
  $b->execute([$u['id']]);

  echo json_encode([
    'ok' => true,
    'rows' => $allRows,
    'balance' => money($b->fetchColumn()),
    'stats' => [
      'today_total' => $todayTotal,
      'today_success' => $todaySuccess,
      'live_pending' => $livePending,
      'today_failed' => $todayFailed,
    ]
  ]);
  exit;
}

echo json_encode(['ok' => false, 'error' => 'Unknown action']);