<?php
@ini_set('display_errors','0');
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);

require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/db_bootstrap.php';
require_once __DIR__ . '/super_admin_guard.php';
require_once __DIR__ . '/mikrotik_lib.php';
require_once __DIR__ . '/settings_store.php';

if (function_exists('ensure_db')) ensure_db(true);
if (function_exists('require_perm')) @require_perm('can_pppoe_cut_restore');
require_super_admin_confirmation('فتح السرعات / إعادة القيود');

$conn = $GLOBALS['conn'] ?? null;
if (!($conn instanceof mysqli)) {
  http_response_code(500);
  die('Database connection error');
}

function speed_toggle_redirect_back(): void {
  header('Location: subscribers.php');
  exit;
}

function speed_toggle_flash(string $type, string $msg): void {
  $_SESSION[$type] = $msg;
}

function speed_toggle_col_exists(mysqli $conn, string $table, string $col): bool {
  $t = $conn->real_escape_string($table);
  $c = $conn->real_escape_string($col);
  $sql = "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='$t' AND COLUMN_NAME='$c' LIMIT 1";
  $rs = @$conn->query($sql);
  return ($rs && $rs->num_rows > 0);
}

function speed_toggle_ensure_backup_table(mysqli $conn): void {
  @$conn->query("CREATE TABLE IF NOT EXISTS ppp_open_all_backup (
    id INT AUTO_INCREMENT PRIMARY KEY,
    subscriber_id INT NULL,
    username VARCHAR(128) NOT NULL,
    original_profile VARCHAR(128) NOT NULL DEFAULT '',
    original_rate_limit VARCHAR(255) NOT NULL DEFAULT '',
    backup_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uq_username (username)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
}

function speed_toggle_backup_count(mysqli $conn): int {
  speed_toggle_ensure_backup_table($conn);
  $rs = @$conn->query("SELECT COUNT(*) c FROM ppp_open_all_backup");
  if ($rs && ($row = $rs->fetch_assoc())) return (int)($row['c'] ?? 0);
  return 0;
}

function speed_toggle_backup_rows(mysqli $conn): array {
  speed_toggle_ensure_backup_table($conn);
  $rows = [];
  $rs = @$conn->query("SELECT * FROM ppp_open_all_backup ORDER BY id ASC");
  if ($rs) { while ($r = $rs->fetch_assoc()) $rows[] = $r; }
  return $rows;
}

function speed_toggle_target_users(mysqli $conn): array {
  $where = speed_toggle_col_exists($conn,'subscribers','is_deleted') ? 'WHERE COALESCE(is_deleted,0)=0' : '';
  $sql = "SELECT id, username"
    . (speed_toggle_col_exists($conn,'subscribers','ppp_username') ? ', ppp_username' : '')
    . (speed_toggle_col_exists($conn,'subscribers','ppp_profile') ? ', ppp_profile' : '')
    . (speed_toggle_col_exists($conn,'subscribers','mt_profile') ? ', mt_profile' : '')
    . " FROM subscribers {$where}";
  $rs = @$conn->query($sql);
  $out = [];
  if ($rs) {
    while ($r = $rs->fetch_assoc()) {
      $u = trim((string)($r['ppp_username'] ?? ''));
      if ($u === '') $u = trim((string)($r['username'] ?? ''));
      if ($u === '') continue;
      $fallbackProfile = trim((string)($r['ppp_profile'] ?? ''));
      if ($fallbackProfile === '') $fallbackProfile = trim((string)($r['mt_profile'] ?? ''));
      $out[$u] = [
        'subscriber_id' => (int)($r['id'] ?? 0),
        'fallback_profile' => $fallbackProfile,
      ];
    }
  }
  return $out;
}

function speed_toggle_setting_mode(mysqli $conn, bool $enabled): void {
  if (function_exists('setting_set')) {
    @setting_set($conn, 'ppp_open_all_mode', $enabled ? '1' : '0');
    @setting_set($conn, 'ppp_open_all_updated_at', date('Y-m-d H:i:s'));
  }
}

function speed_toggle_invalidate_unsafe_cache(): void {
  @unlink(__DIR__ . '/cache/runtime/unsafe_speed_count.json');
}

function speed_toggle_mark_subscriber(mysqli $conn, int $subscriberId, bool $open, string $openProfile = 'OPEN-ALL-UNLIMITED', string $originalProfile = '', string $originalRate = ''): void {
  if ($subscriberId <= 0) return;
  $sets = [];
  if (speed_toggle_col_exists($conn, 'subscribers', 'speed_state')) $sets[] = "speed_state='" . ($open ? 'OPEN_SPEED' : 'ORIGINAL') . "'";
  if (speed_toggle_col_exists($conn, 'subscribers', 'ppp_profile')) {
    $sets[] = "ppp_profile='" . $conn->real_escape_string($open ? $openProfile : $originalProfile) . "'";
  }
  if (speed_toggle_col_exists($conn, 'subscribers', 'ppp_rate_limit')) {
    $sets[] = "ppp_rate_limit='" . $conn->real_escape_string($open ? '' : $originalRate) . "'";
  }
  if ($sets) @$conn->query('UPDATE subscribers SET ' . implode(',', $sets) . ' WHERE id=' . (int)$subscriberId);
}

$action = strtolower(trim((string)($_GET['action'] ?? '')));
if (!in_array($action, ['open','restore'], true)) {
  speed_toggle_flash('flash_warning', 'العملية المطلوبة غير صحيحة.');
  speed_toggle_redirect_back();
}

$api = mt_api($conn);
if (!$api) {
  speed_toggle_flash('flash_warning', (string)($GLOBALS['mt_last_error'] ?? 'فشل الاتصال بالمايكروتك.'));
  speed_toggle_redirect_back();
}

try {
  speed_toggle_ensure_backup_table($conn);
  $openProfile = 'OPEN-ALL-UNLIMITED';

  if ($action === 'open') {
    if (speed_toggle_backup_count($conn) > 0 || ((string)setting_get($conn, 'ppp_open_all_mode', '0') === '1')) {
      speed_toggle_setting_mode($conn, true);
      speed_toggle_flash('flash_warning', 'السرعات المفتوحة مفعلة مسبقاً.');
      speed_toggle_redirect_back();
    }

    if (!mt_ppp_profile_ensure($conn, $openProfile, '')) {
      throw new RuntimeException((string)($GLOBALS['mt_last_error'] ?? 'تعذر تجهيز بروفايل السرعة المفتوحة.'));
    }

    $targets = speed_toggle_target_users($conn);
    if (!$targets) {
      speed_toggle_flash('flash_warning', 'لا يوجد مشتركون صالحون للتنفيذ.');
      speed_toggle_redirect_back();
    }

    $secrets = mt_ppp_secrets_map($api, true);
    if (!$secrets) {
      throw new RuntimeException((string)($GLOBALS['mt_last_error'] ?? 'تعذر قراءة حسابات PPP من المايكروتك.'));
    }

    $stmt = @$conn->prepare("INSERT INTO ppp_open_all_backup(subscriber_id,username,original_profile,original_rate_limit) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE subscriber_id=VALUES(subscriber_id), original_profile=VALUES(original_profile), original_rate_limit=VALUES(original_rate_limit)");
    if (!$stmt) throw new RuntimeException('تعذر تجهيز النسخة الاحتياطية لملفات السرعة.');

    $changed = 0;
    foreach ($targets as $username => $meta) {
      if (!isset($secrets[$username])) continue;
      $row = $secrets[$username];
      $secretId = trim((string)($row['id'] ?? $row['.id'] ?? ''));
      if ($secretId === '') {
        $secret = mt_ppp_find_secret_row($api, $username);
        $secretId = trim((string)($secret['.id'] ?? ''));
      }
      if ($secretId === '') continue;

      $origProfile = trim((string)($row['profile'] ?? ''));
      if ($origProfile === '') $origProfile = trim((string)($meta['fallback_profile'] ?? ''));
      $origRate = trim((string)($row['rate_limit'] ?? ''));

      $sid = (int)($meta['subscriber_id'] ?? 0);
      $stmt->bind_param('isss', $sid, $username, $origProfile, $origRate);
      if (!$stmt->execute()) {
        throw new RuntimeException('فشل حفظ النسخة الاحتياطية للحساب: ' . $username);
      }

      $res = $api->command(['/ppp/secret/set', '=.id=' . $secretId, '=profile=' . $openProfile, '=rate-limit=']);
      $msg = '';
      if (mt_rows_has_error($res, $msg)) {
        throw new RuntimeException('فشل فتح سرعة الحساب ' . $username . ': ' . $msg);
      }

      @mt_ppp_active_disconnect($conn, $username);
      speed_toggle_mark_subscriber($conn, $sid, true, $openProfile, $origProfile, $origRate);
      $changed++;
    }

    speed_toggle_setting_mode($conn, true);
    speed_toggle_invalidate_unsafe_cache();
    speed_toggle_flash('flash_success', 'تم فتح السرعات لجميع الحسابات بنجاح. عدد الحسابات المعدلة: ' . $changed);
    speed_toggle_redirect_back();
  }

  $rows = speed_toggle_backup_rows($conn);
  if (!$rows) {
    speed_toggle_setting_mode($conn, false);
    speed_toggle_flash('flash_warning', 'لا توجد نسخة احتياطية محفوظة لإعادة القيود.');
    speed_toggle_redirect_back();
  }

  $changed = 0;
  foreach ($rows as $r) {
    $username = trim((string)($r['username'] ?? ''));
    if ($username === '') continue;

    $secret = mt_ppp_find_secret_row($api, $username);
    $secretId = trim((string)($secret['.id'] ?? ''));
    if ($secretId === '') continue;

    $originalProfile = trim((string)($r['original_profile'] ?? ''));
    $originalRate = trim((string)($r['original_rate_limit'] ?? ''));
    if ($originalProfile === '') {
      throw new RuntimeException('البروفايل الأصلي مفقود للحساب: ' . $username);
    }

    $args = ['/ppp/secret/set', '=.id=' . $secretId, '=profile=' . $originalProfile, '=rate-limit=' . $originalRate];
    $res = $api->command($args);
    $msg = '';
    if (mt_rows_has_error($res, $msg)) {
      throw new RuntimeException('فشل إعادة القيود للحساب ' . $username . ': ' . $msg);
    }

    @mt_ppp_active_disconnect($conn, $username);
    speed_toggle_mark_subscriber($conn, (int)($r['subscriber_id'] ?? 0), false, $openProfile, $originalProfile, $originalRate);
    $changed++;
  }

  @$conn->query("TRUNCATE TABLE ppp_open_all_backup");
  speed_toggle_setting_mode($conn, false);
  speed_toggle_invalidate_unsafe_cache();
  speed_toggle_flash('flash_success', 'تمت إعادة جميع القيود الأصلية بنجاح. عدد الحسابات المعدلة: ' . $changed);
  speed_toggle_redirect_back();

} catch (Throwable $e) {
  speed_toggle_flash('flash_warning', 'فشل التنفيذ: ' . $e->getMessage());
  speed_toggle_redirect_back();
} finally {
  try { if ($api) $api->disconnect(); } catch (Throwable $e) {}
}
