<?php
require_once __DIR__ . '/airmax_ui_assets.php';
airmax_ui_prepare_page();
$page_title = 'إدارة الأجهزة';
$uaAndroidAirmaxSettings = ((string)($_GET['ua_android'] ?? '') === '1')
  || stripos((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 'NetworkCustomersAndroid/') !== false;
if ($uaAndroidAirmaxSettings) $UA_PAGE_CSS = ['assets/css/pages/airmax_admin.css','assets/css/android_airmax_settings.css'];
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/db_bootstrap.php';
if (function_exists('ensure_db')) ensure_db(true);
require_once __DIR__ . '/airmax_monitor_lib.php';
require_once __DIR__ . '/event_translation_lib.php';
require_once __DIR__ . '/router_port_match_lib.php';

$conn = $GLOBALS['conn'] ?? null;
if (!($conn instanceof mysqli)) { die('DB not ready'); }
airmax_seed_defaults($conn);
airmax_ensure_probe_schema($conn);
$vendorOptions = airmax_vendor_options();
$rxrRouters = function_exists('ua_rpm_router_list') ? ua_rpm_router_list($conn) : [];
$rxrRouterPortSources = function_exists('ua_rx_router_port_sources_active') ? ua_rx_router_port_sources_active() : [];

function airmax_settings_col_exists(mysqli $conn, string $table, string $col): bool {
    static $cache = [];
    $k = $table . '|' . $col;
    if (array_key_exists($k, $cache)) return $cache[$k];
    $t = $conn->real_escape_string($table);
    $c = $conn->real_escape_string($col);
    $rs = @$conn->query("SHOW COLUMNS FROM `{$t}` LIKE '{$c}'");
    return $cache[$k] = (bool)($rs && $rs->num_rows > 0);
}

function airmax_settings_table_exists(mysqli $conn, string $table): bool {
    static $cache = [];
    if (array_key_exists($table, $cache)) return $cache[$table];
    $t = $conn->real_escape_string($table);
    $rs = @$conn->query("SHOW TABLES LIKE '{$t}'");
    return $cache[$table] = (bool)($rs && $rs->num_rows > 0);
}

function airmax_settings_sector_options(mysqli $conn): array {
    if (!airmax_settings_table_exists($conn, 'sectors')) return [];
    $cols = ['id','name'];
    if (airmax_settings_col_exists($conn, 'sectors', 'vlan_id')) $cols[] = 'vlan_id';
    $sql = 'SELECT ' . implode(',', array_map(static fn($c) => '`'.$c.'`', $cols)) . ' FROM sectors ORDER BY name ASC, id ASC';
    $rs = @$conn->query($sql);
    $out = [];
    if ($rs) {
        while ($r = $rs->fetch_assoc()) {
            $id = (int)($r['id'] ?? 0);
            if ($id <= 0) continue;
            $name = trim((string)($r['name'] ?? ''));
            $vlan = isset($r['vlan_id']) ? (int)$r['vlan_id'] : 0;
            $out[$id] = ['id'=>$id,'name'=>$name !== '' ? $name : ('#'.$id),'vlan_id'=>$vlan];
        }
    }
    return $out;
}

$sectorOptions = airmax_settings_sector_options($conn);

$msg = '';
$msgType = 'success';
$activeTab = in_array((string)($_POST['open_tab'] ?? $_GET['tab'] ?? ''), ['devices','router-match','device-log'], true)
    ? (string)($_POST['open_tab'] ?? $_GET['tab'])
    : 'devices';
$selectedDeviceLogId = (int)($_POST['device_log_id'] ?? $_POST['id'] ?? 0);

function airmax_settings_db_error(mysqli $conn, ?mysqli_stmt $st = null): string {
    $e = '';
    if ($st instanceof mysqli_stmt && trim((string)$st->error) !== '') $e = (string)$st->error;
    if ($e === '' && trim((string)$conn->error) !== '') $e = (string)$conn->error;
    return $e !== '' ? $e : 'خطأ غير معروف في قاعدة البيانات';
}

function airmax_detect_best_route(array $d): array {
    $metrics = airmax_try_fetch_details($d, 5.5);
    if (!empty($metrics['_route']) && is_array($metrics['_route'])) {
        return [
            'ok' => true,
            'protocol' => strtolower((string)($metrics['_route']['protocol'] ?? ($d['protocol'] ?? 'https'))),
            'port' => (int)($metrics['_route']['port'] ?? ($d['port'] ?? 443)),
            'mode' => (string)($metrics['_route']['mode'] ?? ''),
            'metrics' => $metrics,
        ];
    }
    return ['ok' => false, 'metrics' => $metrics];
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        if (isset($_POST['save_device'])) {
            $id = (int)($_POST['id'] ?? 0);
            $isNewDevice = $id <= 0;
            $name = trim((string)($_POST['name'] ?? ''));
            $type = function_exists('airmax_device_role') ? airmax_device_role($_POST['device_type'] ?? 'access') : (((string)($_POST['device_type'] ?? 'access') === 'station') ? 'station' : 'access');
            $host = trim((string)($_POST['host'] ?? ''));
            $proto = strtolower(trim((string)($_POST['protocol'] ?? 'https'))) === 'http' ? 'http' : 'https';
            $port = (int)($_POST['port'] ?? ($proto === 'http' ? 80 : 443));
            $preferredVendor = strtolower(trim((string)($_POST['preferred_vendor'] ?? 'auto')));
            if (!array_key_exists($preferredVendor, $vendorOptions)) $preferredVendor = 'auto';
            $snmpCommunity = trim((string)($_POST['snmp_community'] ?? 'public'));
            if ($snmpCommunity === '') $snmpCommunity = 'public';
            $user = trim((string)($_POST['username'] ?? ''));
            $pass = trim((string)($_POST['password'] ?? ''));
            $notes = trim((string)($_POST['notes'] ?? ''));
            $enabled = !empty($_POST['is_enabled']) ? 1 : 0;
            $sort = (int)($_POST['sort_order'] ?? 0);
            $sectorId = (int)($_POST['sector_id'] ?? 0);
            if ($sectorId > 0 && !isset($sectorOptions[$sectorId])) $sectorId = 0;
            $parentDeviceId = (int)($_POST['parent_device_id'] ?? 0);
            if ($parentDeviceId === $id) $parentDeviceId = 0;
            if ($parentDeviceId > 0) {
                $chkParent = @$conn->prepare('SELECT id FROM airmax_devices WHERE id=?' . ($id > 0 ? ' AND id<>?' : ''));
                $parentOk = false;
                if ($chkParent) {
                    if ($id > 0) $chkParent->bind_param('ii', $parentDeviceId, $id); else $chkParent->bind_param('i', $parentDeviceId);
                    @$chkParent->execute();
                    @$chkParent->store_result();
                    $parentOk = $chkParent->num_rows > 0;
                    $chkParent->close();
                }
                if (!$parentOk) $parentDeviceId = 0;
            }

            if ($name === '' || $host === '') {
                $msg = 'الاسم و IP مطلوبان.';
                $msgType = 'danger';
            } else {
                $dupSql = "SELECT id FROM airmax_devices WHERE host=?" . ($id > 0 ? " AND id<>?" : "");
                $dup = @$conn->prepare($dupSql);
                $dupId = 0;
                if ($dup) {
                    if ($id > 0) $dup->bind_param('si', $host, $id);
                    else $dup->bind_param('s', $host);
                    @$dup->execute();
                    @$dup->bind_result($dupId);
                    @$dup->fetch();
                    $dup->close();
                }

                if ($dupId > 0) {
                    $msg = 'هذا الـ IP مضاف مسبقًا. لا يمكن تكرار نفس العنوان.';
                    $msgType = 'danger';
                } else {
                    $savedOk = false;
                    if ($id > 0) {
                        $st = $conn->prepare("UPDATE airmax_devices SET name=?, device_type=?, host=?, protocol=?, port=?, preferred_vendor=?, snmp_community=?, username=?, password=?, notes=?, sort_order=?, is_enabled=?, sector_id=?, parent_device_id=?, probe_locked=0, probe_status='idle', probe_progress=0, probe_message=NULL WHERE id=?");
                        if ($st) {
                            $st->bind_param('ssssisssssiiiii', $name, $type, $host, $proto, $port, $preferredVendor, $snmpCommunity, $user, $pass, $notes, $sort, $enabled, $sectorId, $parentDeviceId, $id);
                            $savedOk = $st->execute();
                            if (!$savedOk) {
                                $msg = 'تعذر حفظ الجهاز: ' . airmax_settings_db_error($conn, $st);
                                $msgType = 'danger';
                            }
                            $st->close();
                        } else {
                            $msg = 'تعذر تجهيز أمر الحفظ: ' . airmax_settings_db_error($conn, null);
                            $msgType = 'danger';
                        }
                    } else {
                        $st = $conn->prepare("INSERT INTO airmax_devices (name,device_type,host,protocol,port,preferred_vendor,snmp_community,username,password,notes,sort_order,is_enabled,sector_id,parent_device_id,probe_status,probe_progress,probe_locked) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,'idle',0,0)");
                        if ($st) {
                            $st->bind_param('ssssisssssiiii', $name, $type, $host, $proto, $port, $preferredVendor, $snmpCommunity, $user, $pass, $notes, $sort, $enabled, $sectorId, $parentDeviceId);
                            $savedOk = $st->execute();
                            if ($savedOk) {
                                $id = (int)$conn->insert_id;
                            } else {
                                $msg = 'تعذر إضافة الجهاز: ' . airmax_settings_db_error($conn, $st);
                                $msgType = 'danger';
                            }
                            $st->close();
                        } else {
                            $msg = 'تعذر تجهيز أمر الإضافة: ' . airmax_settings_db_error($conn, null);
                            $msgType = 'danger';
                        }
                    }

                    if ($savedOk && $id > 0) {
                        @unlink(__DIR__ . '/cache/runtime/receiver_matches/snapshot.json');
                        @unlink(__DIR__ . '/cache/runtime/receiver_matches/snapshot.lock');
                        $device = [
                            'id' => $id,
                            'name' => $name,
                            'device_type' => $type,
                            'host' => $host,
                            'protocol' => $proto,
                            'port' => $port,
                            'preferred_vendor' => $preferredVendor,
                            'snmp_community' => $snmpCommunity,
                            'username' => $user,
                            'password' => $pass,
                            'notes' => $notes,
                            'sort_order' => $sort,
                            'is_enabled' => $enabled,
                            'sector_id' => $sectorId,
                            'parent_device_id' => $parentDeviceId,
                        ];
                        if (function_exists('airmax_device_log_event')) {
                            airmax_device_log_event($conn, $device, $isNewDevice ? 'DEVICE_CREATED' : 'DEVICE_SAVED', 'success', 'status=success; action=' . ($isNewDevice ? 'device_created' : 'device_saved') . '; device=' . $name . '; host=' . $host . '; type=' . $type, [
                                'action' => $isNewDevice ? 'add_device' : 'save_device',
                                'device_type' => $type,
                                'host' => $host,
                                'protocol' => $proto,
                                'port' => $port,
                                'preferred_vendor' => $preferredVendor,
                                'sector_id' => $sectorId,
                                'parent_device_id' => $parentDeviceId,
                                'enabled' => (bool)$enabled,
                            ], 'device_settings');
                        }
                        $det = airmax_detect_best_route($device);
                        if (!empty($det['ok'])) {
                            $proto = $det['protocol'];
                            $port = $det['port'];
                            $mode = (string)($det['mode'] ?? '');
                            $detMetrics = is_array($det['metrics'] ?? null) ? $det['metrics'] : [];
                            $detRoute = is_array($detMetrics['_route'] ?? null) ? $detMetrics['_route'] : [];
                            $detVendor = function_exists('airmax_preferred_vendor') ? airmax_preferred_vendor($detMetrics['vendor'] ?? ($detRoute['vendor'] ?? $preferredVendor)) : (string)($detMetrics['vendor'] ?? $preferredVendor);
                            if ($detVendor === 'auto') $detVendor = (($mode === 'mimosa_rest' || $mode === 'mimosa_webui') ? 'mimosa' : 'ubiquiti');
                            $detOs = (string)($detMetrics['os'] ?? ($detVendor === 'mimosa' ? 'MimosaOS' : ($mode === 'airos8' ? 'airOS' : 'airOSClassic')));
                            $display = strtoupper($proto) . ':' . $port . ($mode !== '' ? ' | ' . $mode : '');
                            $up = @$conn->prepare("UPDATE airmax_devices SET protocol=?, port=?, detected_protocol=?, detected_port=?, detected_vendor=?, detected_os=?, detected_mode=?, detected_route=?, probe_status='partial', probe_progress=100, probe_message='تم تثبيت مسار أولي تلقائياً', probe_locked=0 WHERE id=?");
                            if ($up) {
                                $up->bind_param('sissssssi', $proto, $port, $proto, $port, $detVendor, $detOs, $mode, $display, $id);
                                @$up->execute();
                                $up->close();
                            }
                            if (function_exists('airmax_route_cache_set')) {
                                airmax_route_cache_set($device, ['protocol' => $proto, 'port' => $port, 'mode' => $mode, 'vendor' => $detVendor, 'os' => $detOs]);
                            }
                            $msg = 'تم حفظ الجهاز بنجاح وتثبيت مسار أولي تلقائيًا: ' . strtoupper($proto) . ':' . (int)$port;
                            $msgType = 'success';
                        } else {
                            $msg = 'تم حفظ الجهاز. يمكنك الآن تشغيل زر فحص المنفذ لاكتشاف المسار تلقائياً.';
                            $msgType = 'warning';
                        }
                    } elseif ($msg === '') {
                        $msg = 'تعذر حفظ الجهاز.';
                        $msgType = 'danger';
                    }
                }
            }
        }

        if (isset($_POST['pull_device_log'])) {
            $activeTab = 'device-log';
            $id = (int)($_POST['id'] ?? ($_POST['device_log_id'] ?? 0));
            if ($id > 0) {
                $dq = @$conn->query("SELECT * FROM airmax_devices WHERE id=" . (int)$id . " LIMIT 1");
                $device = ($dq && $dq->num_rows) ? $dq->fetch_assoc() : null;
                if (!$device) {
                    $msg = 'لم يتم العثور على الجهاز المطلوب.';
                    $msgType = 'danger';
                } else {
                    $pull = function_exists('airmax_fetch_device_native_log') ? airmax_fetch_device_native_log($conn, $device) : ['ok'=>false, 'log'=>'', 'error'=>'دالة سحب اللوج غير متاحة.', 'details'=>[]];
                    $ok = !empty($pull['ok']);
                    $rawLog = $ok ? (string)($pull['log'] ?? '') : (string)($pull['error'] ?? '');
                    $details = is_array($pull['details'] ?? null) ? $pull['details'] : [];
                    $details['action'] = 'pull_native_device_log';
                    if (function_exists('airmax_device_log_event')) {
                        airmax_device_log_event(
                            $conn,
                            $device,
                            'DEVICE_NATIVE_LOG',
                            $ok ? 'success' : 'failed',
                            $rawLog,
                            $details,
                            'device_native_log'
                        );
                    }
                    if ($ok) {
                        $msg = 'تمت قراءة سجل الجهاز وحفظه في سجل الأجهزة.';
                        $msgType = 'success';
                    } else {
                        $msg = 'تعذرت قراءة سجل الجهاز: ' . ($rawLog !== '' ? $rawLog : 'سبب غير معروف');
                        $msgType = 'danger';
                    }
                }
            }
        }

        if (isset($_POST['delete_device'])) {
            $id = (int)($_POST['id'] ?? 0);
            if ($id > 0) {
                $deletedDevice = null;
                $dq = @$conn->query("SELECT * FROM airmax_devices WHERE id=" . (int)$id . " LIMIT 1");
                if ($dq && $dq->num_rows) $deletedDevice = $dq->fetch_assoc();
                if ($deletedDevice && function_exists('airmax_device_log_event')) {
                    airmax_device_log_event($conn, $deletedDevice, 'DEVICE_DELETED', 'success', 'status=success; action=device_deleted; device=' . (string)($deletedDevice['name'] ?? '') . '; host=' . (string)($deletedDevice['host'] ?? ''), [
                        'action' => 'delete_device',
                        'device_id' => $id,
                        'device_name' => (string)($deletedDevice['name'] ?? ''),
                        'host' => (string)($deletedDevice['host'] ?? ''),
                    ], 'device_settings');
                }
                @$conn->query("UPDATE airmax_devices SET parent_device_id=NULL WHERE parent_device_id=" . (int)$id); @$conn->query("DELETE FROM airmax_devices WHERE id=" . (int)$id); @unlink(__DIR__ . '/cache/runtime/receiver_matches/snapshot.json'); @unlink(__DIR__ . '/cache/runtime/receiver_matches/snapshot.lock');
            }
            $msg = 'تم حذف الجهاز';
            $msgType = 'success';
        }
    } catch (Throwable $e) {
        $msg = 'حدث خطأ أثناء الحفظ: ' . $e->getMessage();
        $msgType = 'danger';
    }
}

$devices = airmax_get_all($conn, false);
$deviceLogRows = [];
$deviceLogLastFailure = null;
$deviceSystemLogCount = 0;
$deviceLogRs = @$conn->query("SELECT id,device_id,device_name,host,device_type,event_source,event_key,status,raw_event,arabic_summary,details_json,event_at FROM device_activity_log WHERE event_source='device_native_log' AND status IN ('success','ok') ORDER BY event_at DESC, id DESC LIMIT 120");
if ($deviceLogRs) {
    while ($r = $deviceLogRs->fetch_assoc()) $deviceLogRows[] = $r;
}
if ($selectedDeviceLogId <= 0 && !empty($deviceLogRows[0]['device_id'])) $selectedDeviceLogId = (int)$deviceLogRows[0]['device_id'];
if ($selectedDeviceLogId > 0) {
    $selectedLogId = (int)$selectedDeviceLogId;
    $deviceLogFailRs = @$conn->query("SELECT id,device_id,device_name,host,device_type,event_source,event_key,status,raw_event,arabic_summary,details_json,event_at FROM device_activity_log WHERE event_source='device_native_log' AND device_id={$selectedLogId} ORDER BY event_at DESC, id DESC LIMIT 1");
    if ($deviceLogFailRs && $deviceLogFailRs->num_rows) {
        $latestSelectedLog = $deviceLogFailRs->fetch_assoc();
        $latestStatus = strtolower((string)($latestSelectedLog['status'] ?? ''));
        if (!in_array($latestStatus, ['success','ok'], true)) $deviceLogLastFailure = $latestSelectedLog;
    }
}
$deviceSystemLogCountRs = @$conn->query("SELECT COUNT(*) c FROM device_activity_log WHERE event_source<>'device_native_log' OR event_source IS NULL");
if ($deviceSystemLogCountRs && ($row = $deviceSystemLogCountRs->fetch_assoc())) $deviceSystemLogCount = (int)($row['c'] ?? 0);
function airmax_parent_select_options(array $devices, int $currentId = 0): array {
    $out = [];
    foreach ($devices as $dev) {
        $id = (int)($dev['id'] ?? 0);
        if ($id <= 0 || $id === $currentId) continue;
        $label = trim((string)($dev['name'] ?? ''));
        $host = trim((string)($dev['host'] ?? ''));
        $role = function_exists('airmax_device_role_text') ? airmax_device_role_text((string)($dev['device_type'] ?? 'access')) : (string)($dev['device_type'] ?? '');
        if ($label === '') $label = '#' . $id;
        if ($host !== '') $label .= ' — ' . $host;
        if ($role !== '') $label .= ' — ' . $role;
        $out[$id] = $label;
    }
    return $out;
}
if (!defined('UA_EMBED')) define('UA_EMBED', isset($_GET['embed']) && $_GET['embed'] == '1');
if (UA_EMBED && function_exists('airmax_ui_print_embed_assets')) { airmax_ui_print_embed_assets(); }
if (!UA_EMBED) {
    require_once __DIR__ . '/header.php';
    require_once __DIR__ . '/sidebar.php';
}

function airmax_probe_badge_class(string $status): string {
    return match ($status) {
        'success' => 'success',
        'partial' => 'warning',
        'failed' => 'danger',
        'running' => 'info',
        default => 'secondary',
    };
}

function airmax_probe_badge_text(string $status): string {
    return match ($status) {
        'success' => 'جاهز',
        'partial' => 'جزئي',
        'failed' => 'فشل',
        'running' => 'جارٍ',
        default => 'معلّق',
    };
}

function airmax_device_type_text(string $type): string {
    if (function_exists('airmax_device_role_text')) return airmax_device_role_text($type);
    return $type === 'station' ? 'Station / مستقبل' : 'Access / قطاع';
}

function airmax_device_log_action_text(string $eventKey, string $source = '', string $raw = ''): string {
    $key = strtoupper(trim($eventKey));
    $src = strtolower(trim($source));
    $haystack = strtolower($key . ' ' . $src . ' ' . $raw);
    if ($key === 'DEVICE_NATIVE_LOG' || $src === 'device_native_log') return 'قراءة سجل الجهاز';
    if ($key === 'DEVICE_CREATED' || str_contains($haystack, 'device_created')) return 'إضافة جهاز';
    if ($key === 'DEVICE_SAVED' || str_contains($haystack, 'device_saved')) return 'حفظ إعدادات';
    if ($key === 'DEVICE_DELETED' || str_contains($haystack, 'device_deleted')) return 'حذف جهاز';
    if ($key === 'DEVICE_PROBE') return 'فحص جهاز';
    if (str_contains($haystack, 'router')) return 'جلب من الراوتر';
    return 'حركة جهاز';
}

function airmax_device_log_source_text(string $source): string {
    $source = strtolower(trim($source));
    return match ($source) {
        'device_settings' => 'إدارة الأجهزة',
        'airmax_probe' => 'فحص الأجهزة',
        'device_native_log' => 'سجل الجهاز',
        'router_match', 'router_port_match' => 'مطابقة الراوتر',
        default => $source !== '' ? $source : 'النظام',
    };
}

function airmax_device_log_status_text(string $status): string {
    $status = strtolower(trim($status));
    return match ($status) {
        'success', 'ok' => 'نجاح',
        'partial' => 'جزئي',
        'running' => 'جارٍ',
        'failed', 'error' => 'فشل',
        default => $status !== '' ? $status : 'غير محدد',
    };
}

function airmax_device_log_status_class(string $status): string {
    $status = strtolower(trim($status));
    if ($status === 'success' || $status === 'ok') return 'success';
    if ($status === 'partial' || $status === 'running') return 'warning';
    if ($status === 'failed' || $status === 'error') return 'danger';
    return 'secondary';
}

function airmax_device_log_details(array $row): array {
    $rawJson = (string)($row['details_json'] ?? '');
    $details = json_decode($rawJson, true);
    if (!is_array($details)) $details = [];
    $out = [];
    $map = [
        'message' => 'الرسالة',
        'route' => 'المسار',
        'protocol' => 'البروتوكول',
        'port' => 'المنفذ',
        'mode' => 'النمط',
        'vendor' => 'الشركة',
        'os' => 'النظام',
        'client_count_method' => 'طريقة العد',
        'bridge_path' => 'مسار Bridge',
        'last_error' => 'آخر خطأ',
        'action' => 'الإجراء',
        'method' => 'طريقة السحب',
        'path' => 'مسار اللوج',
        'log_lines' => 'أسطر LOG',
        'dmesg_lines' => 'أسطر DMESG',
        'total_lines' => 'إجمالي الأسطر',
    ];
    foreach ($map as $key => $label) {
        if (!array_key_exists($key, $details)) continue;
        $value = $details[$key];
        if (is_bool($value)) $value = $value ? 'نعم' : 'لا';
        if (is_array($value) || is_object($value)) $value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $value = trim((string)$value);
        if ($value === '') continue;
        $out[] = [$label, $value];
    }
    return $out;
}
if ($uaAndroidAirmaxSettings && !UA_EMBED) {
    require __DIR__ . '/android_airmax_settings.php';
    require_once __DIR__ . '/footer.php';
    exit;
}
?>
<?php if (!UA_EMBED): ?><div class="content-wrapper ua-extracted-page"><section class="content p-3"><?php endif; ?>
<div class="ua-airmax-scope" dir="rtl">
<div class="card airmax-card">
  <div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
    <h3 class="card-title mb-0">إدارة الأجهزة</h3>
  </div>
  <div class="card-body">
    <?php if ($msg): ?>
      <div class="alert alert-<?= htmlspecialchars($msgType, ENT_QUOTES, 'UTF-8') ?> mb-3"><?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8') ?></div>
    <?php endif; ?>

    <div class="airmax-local-tabs" role="tablist" aria-label="إدارة أجهزة AirMax">
      <div class="airmax-local-tab-buttons">
        <button type="button" class="airmax-local-tab <?= $activeTab === 'devices' ? 'is-active' : '' ?>" data-airmax-tab="devices">إضافة وإدارة الهوائيات</button>
        <button type="button" class="airmax-local-tab <?= $activeTab === 'router-match' ? 'is-active' : '' ?>" data-airmax-tab="router-match">الجلب والمطابقة من الراوتر</button>
        <button type="button" class="airmax-local-tab <?= $activeTab === 'device-log' ? 'is-active' : '' ?>" data-airmax-tab="device-log">سجل الأجهزة</button>
      </div>
      <div class="airmax-local-tools">
        <details class="airmax-help">
          <summary aria-label="شرح إعدادات أجهزة AirMax" title="شرح إعدادات أجهزة AirMax">؟</summary>
          <div class="airmax-help-panel">
            يكفي إدخال الاسم + IP + بيانات الدخول. اختر نوع الجهاز بدقة: <strong>Access/قطاع</strong> لا يدخل في مطابقة المشتركين نهائياً، و <strong>Station/مستقبل</strong> فقط يتم استخدام MACات LAN0 منه للمطابقة. إذا كان المستقبل متغذياً من جهاز آخر، اختره من حقل <strong>متصل خلف</strong> حتى تُنسب الماكات إلى أقرب Station في المسار. بعد الحفظ شغّل <strong>فحص المنفذ</strong> ليكتشف البروتوكول والمنفذ والشركة والنظام ويحفظ المسار الناجح تلقائياً. أجهزة Mimosa تستخدم REST الرسمي للقراءات العامة، وSNMP لقراءة MACات Ethernet عند توفر Bridge FDB.
          </div>
        </details>
        <button type="button" class="btn btn-sm btn-primary" data-airmax-add-new><i class="fa fa-plus" aria-hidden="true"></i> إضافة جهاز</button>
        <a href="receiver_match_report.php" class="btn btn-sm btn-warning">تقرير المطابقة</a>
        <a href="dashboard.php" class="btn btn-sm btn-outline-primary">العودة إلى لوحة المراقبة</a>
      </div>
    </div>

    <div class="airmax-tab-panel <?= $activeTab === 'devices' ? 'is-active' : '' ?>" data-airmax-panel="devices" <?= $activeTab === 'devices' ? '' : 'hidden' ?>>
    <div class="table-responsive">
      <form method="post" id="airmax-device-form-new"></form>
      <table class="table table-bordered table-sm airmax-settings-table" dir="rtl">
        <thead>
          <tr>
            <th class="col-id">#</th>
            <th class="col-name">الجهاز</th>
            <th class="col-host">العنوان</th>
            <th class="col-access">الدخول</th>
            <th class="col-config">الترتيب/التفعيل</th>
            <th class="col-probe">نتيجة الفحص</th>
            <th class="col-actions">العمليات</th>
          </tr>
        </thead>
        <tbody>
        <?php foreach ($devices as $d): ?>
          <?php
            $status = (string)($d['probe_status'] ?? 'idle');
            $routeText = trim((string)($d['detected_route'] ?? ''));
            if ($routeText === '') $routeText = strtoupper((string)$d['protocol']) . ':' . (int)$d['port'];
            $message = trim((string)($d['probe_message'] ?? ''));
            if ($message === '') $message = 'بانتظار الفحص';
            $vendorText = trim((string)($vendorOptions[(string)($d['preferred_vendor'] ?? 'auto')] ?? 'تلقائي'));
            $detectedVendor = trim((string)($d['detected_vendor'] ?? ''));
            $detectedOs = trim((string)($d['detected_os'] ?? ''));
            $metaParts = [];
            if ($detectedVendor !== '') $metaParts[] = $detectedVendor;
            if ($detectedOs !== '') $metaParts[] = $detectedOs;
            if (!$metaParts) $metaParts[] = 'تفضيل الشركة: ' . $vendorText;
          ?>
          <tr data-airmax-form="airmax-device-form-<?= (int)$d['id'] ?>" data-airmax-device-row>
              <td class="airmax-id-cell">
                <form method="post" id="airmax-device-form-<?= (int)$d['id'] ?>"></form>
                <div class="airmax-id"><?= (int)$d['id'] ?></div>
                <input type="hidden" name="id" value="<?= (int)$d['id'] ?>">
              </td>
              <td>
                <div class="airmax-device-stack">
                  <div class="airmax-row-summary airmax-device-name-summary">
                    <strong><?= htmlspecialchars((string)$d['name'], ENT_QUOTES, 'UTF-8') ?></strong>
                    <span><?= htmlspecialchars(airmax_device_type_text((string)$d['device_type']), ENT_QUOTES, 'UTF-8') ?></span>
                  </div>
                  <input class="form-control form-control-sm airmax-input" name="name" value="<?= htmlspecialchars((string)$d['name'], ENT_QUOTES, 'UTF-8') ?>">
                  <div class="airmax-subline"><?= htmlspecialchars(airmax_device_type_text((string)$d['device_type']), ENT_QUOTES, 'UTF-8') ?></div>
                  <?php $role = function_exists('airmax_device_role') ? airmax_device_role($d['device_type'] ?? 'access') : ((string)($d['device_type'] ?? 'access')); ?>
                  <select class="form-control form-control-sm airmax-input" name="device_type" title="Station فقط يدخل في مطابقة المشتركين عبر LAN0">
                    <option value="access" <?= $role === 'access' ? 'selected' : '' ?>>Access / قطاع - لا يدخل بالمطابقة</option>
                    <option value="station" <?= $role === 'station' ? 'selected' : '' ?>>Station / مستقبل - مطابقة LAN0 فقط</option>
                  </select>
                  <input type="hidden" name="sector_id" value="<?= (int)($d['sector_id'] ?? 0) ?>">
                  <select class="form-control form-control-sm airmax-input" name="parent_device_id" title="حدد الجهاز الذي يتغذى خلفه هذا الجهاز لبناء شجرة التغذية ومنع تضارب الماكات">
                    <option value="0">متصل مباشرة / لا يوجد أب</option>
                    <?php foreach (airmax_parent_select_options($devices, (int)$d['id']) as $pid => $plabel): ?>
                      <option value="<?= (int)$pid ?>" <?= ((int)($d['parent_device_id'] ?? 0) === (int)$pid) ? 'selected' : '' ?>>خلف: <?= htmlspecialchars($plabel, ENT_QUOTES, 'UTF-8') ?></option>
                    <?php endforeach; ?>
                  </select>
                </div>
              </td>
              <td>
                <div class="airmax-device-stack">
                  <div class="airmax-row-summary airmax-host-summary" dir="ltr">
                    <strong><?= htmlspecialchars((string)$d['host'], ENT_QUOTES, 'UTF-8') ?></strong>
                    <span><?= htmlspecialchars($vendorText, ENT_QUOTES, 'UTF-8') ?></span>
                  </div>
                  <input class="form-control form-control-sm airmax-input airmax-host" name="host" value="<?= htmlspecialchars((string)$d['host'], ENT_QUOTES, 'UTF-8') ?>">
                  <select class="form-control form-control-sm airmax-input" name="preferred_vendor">
                    <?php foreach ($vendorOptions as $vk => $vl): ?>
                      <option value="<?= htmlspecialchars($vk, ENT_QUOTES, 'UTF-8') ?>" <?= ((string)($d['preferred_vendor'] ?? 'auto') === $vk) ? 'selected' : '' ?>><?= htmlspecialchars($vl, ENT_QUOTES, 'UTF-8') ?></option>
                    <?php endforeach; ?>
                  </select>
                  <input type="hidden" name="protocol" value="<?= htmlspecialchars((string)$d['protocol'], ENT_QUOTES, 'UTF-8') ?>">
                  <input type="hidden" name="port" value="<?= (int)$d['port'] ?>">
                  <input type="hidden" name="notes" value="<?= htmlspecialchars((string)($d['notes'] ?? ''), ENT_QUOTES, 'UTF-8') ?>">
                </div>
              </td>
              <td>
                <div class="airmax-device-stack">
                  <div class="airmax-row-summary airmax-login-summary">
                    <strong><?= htmlspecialchars((string)($d['username'] ?? ''), ENT_QUOTES, 'UTF-8') ?></strong>
                    <span><?= trim((string)($d['password'] ?? '')) !== '' ? 'بيانات الدخول محفوظة' : 'كلمة المرور غير مكتملة' ?></span>
                  </div>
                  <input class="form-control form-control-sm airmax-input" name="username" value="<?= htmlspecialchars((string)($d['username'] ?? ''), ENT_QUOTES, 'UTF-8') ?>" placeholder="اسم المستخدم">
                  <input class="form-control form-control-sm airmax-input" type="password" name="password" value="<?= htmlspecialchars((string)($d['password'] ?? ''), ENT_QUOTES, 'UTF-8') ?>" placeholder="كلمة المرور">
                  <div class="airmax-snmp-field" <?= ((string)($d['preferred_vendor'] ?? 'auto') === 'mimosa') ? '' : 'style="display:none"' ?>>
                    <input class="form-control form-control-sm airmax-input" name="snmp_community" value="<?= htmlspecialchars((string)($d['snmp_community'] ?? 'public'), ENT_QUOTES, 'UTF-8') ?>" placeholder="SNMP Community">
                  </div>
                </div>
              </td>
              <td>
                <div class="airmax-config-stack">
                  <div class="airmax-row-summary airmax-config-summary">
                    <strong><?= (int)$d['sort_order'] ?></strong>
                    <span><?= !empty($d['is_enabled']) ? 'مفعّل' : 'متوقف' ?></span>
                  </div>
                  <input class="form-control form-control-sm airmax-input airmax-sort" type="number" name="sort_order" value="<?= (int)$d['sort_order'] ?>">
                  <label class="airmax-toggle-wrap">
                    <span>مفعّل</span>
                    <label class="airmax-check"><input type="checkbox" name="is_enabled" value="1" <?= !empty($d['is_enabled']) ? 'checked' : '' ?>><span></span></label>
                  </label>
                </div>
              </td>
              <td class="airmax-probe-cell">
                <div class="airmax-route-text" id="route-<?= (int)$d['id'] ?>"><?= htmlspecialchars($routeText, ENT_QUOTES, 'UTF-8') ?></div>
                <div class="airmax-vendor-os" id="probe-meta-<?= (int)$d['id'] ?>"><?= htmlspecialchars(implode(' | ', $metaParts), ENT_QUOTES, 'UTF-8') ?></div>
                <div class="airmax-probe-progress d-none" id="progress-wrap-<?= (int)$d['id'] ?>">
                  <div class="progress progress-xs mb-1"><div class="progress-bar bg-info ua-u-w-0" id="progress-bar-<?= (int)$d['id'] ?>"></div></div>
                  <div class="airmax-progress-line"><span id="progress-text-<?= (int)$d['id'] ?>">0%</span><span id="progress-stage-<?= (int)$d['id'] ?>">بدء الفحص</span></div>
                </div>
                <div class="airmax-probe-result" id="probe-result-<?= (int)$d['id'] ?>"><?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?></div>
                <span class="badge badge-<?= airmax_probe_badge_class($status) ?>" id="probe-badge-<?= (int)$d['id'] ?>"><?= airmax_probe_badge_text($status) ?></span>
              </td>
              <td class="airmax-actions-cell">
                <div class="airmax-actions-grid">
                  <button type="button" class="btn btn-outline-primary btn-sm airmax-edit-toggle airmax-icon-action" title="تعديل بيانات الجهاز" aria-label="تعديل بيانات الجهاز"><i class="fa fa-pencil" aria-hidden="true"></i></button>
                  <button class="btn btn-success btn-sm airmax-icon-action" name="save_device" value="1" title="حفظ" aria-label="حفظ"><i class="fa fa-save" aria-hidden="true"></i></button>
                  <button class="btn btn-secondary btn-sm airmax-icon-action" name="pull_device_log" value="1" title="قراءة سجل الجهاز" aria-label="قراءة سجل الجهاز"><i class="fa fa-list-alt" aria-hidden="true"></i></button>
                  <button type="button" class="btn btn-warning btn-sm airmax-probe-btn airmax-icon-action" data-id="<?= (int)$d['id'] ?>" title="فحص المنفذ" aria-label="فحص المنفذ" <?= !empty($d['probe_locked']) ? 'disabled' : '' ?>><i class="fa fa-plug" aria-hidden="true"></i></button>
                  <button type="button" class="btn btn-outline-light btn-sm airmax-reprobe-btn airmax-icon-action <?= empty($d['probe_locked']) ? 'd-none' : '' ?>" data-id="<?= (int)$d['id'] ?>" title="إعادة الفحص" aria-label="إعادة الفحص"><i class="fa fa-refresh" aria-hidden="true"></i></button>
                  <a class="btn btn-info btn-sm airmax-icon-action" target="_blank" href="api/airmax_monitor_debug.php?id=<?= (int)$d['id'] ?>&fresh=1" title="Debug" aria-label="Debug"><i class="fa fa-bug" aria-hidden="true"></i></a>
                  <button class="btn btn-danger btn-sm airmax-delete-btn airmax-icon-action" name="delete_device" value="1" title="حذف" aria-label="حذف" onclick="return confirm('حذف الجهاز؟');"><i class="fa fa-trash" aria-hidden="true"></i></button>
                </div>
              </td>
          </tr>
        <?php endforeach; ?>
          <tr class="airmax-add-row is-editing" data-airmax-form="airmax-device-form-new" data-airmax-new-row>
              <td class="airmax-id-cell"><div class="airmax-id airmax-id-new">جديد</div></td>
              <td>
                <div class="airmax-device-stack">
                  <input class="form-control form-control-sm airmax-input" name="name" placeholder="اسم الجهاز">
                  <div class="airmax-subline">اختر النوع ثم احفظ</div>
                  <select class="form-control form-control-sm airmax-input" name="device_type" title="Station فقط يدخل في مطابقة المشتركين عبر LAN0"><option value="access" selected>Access / قطاع - لا يدخل بالمطابقة</option><option value="station">Station / مستقبل - مطابقة LAN0 فقط</option></select>
                  <input type="hidden" name="sector_id" value="0">
                  <select class="form-control form-control-sm airmax-input" name="parent_device_id" title="حدد الجهاز الأب إذا كان هذا الجهاز متغذياً من مستقبل/قطاع آخر">
                    <option value="0" selected>متصل مباشرة / لا يوجد أب</option>
                    <?php foreach (airmax_parent_select_options($devices, 0) as $pid => $plabel): ?>
                      <option value="<?= (int)$pid ?>">خلف: <?= htmlspecialchars($plabel, ENT_QUOTES, 'UTF-8') ?></option>
                    <?php endforeach; ?>
                  </select>
                </div>
              </td>
              <td>
                <div class="airmax-device-stack">
                  <input class="form-control form-control-sm airmax-input airmax-host" name="host" placeholder="10.30.99.x">
                  <select class="form-control form-control-sm airmax-input" name="preferred_vendor">
                    <?php foreach ($vendorOptions as $vk => $vl): ?>
                      <option value="<?= htmlspecialchars($vk, ENT_QUOTES, 'UTF-8') ?>" <?= $vk === 'auto' ? 'selected' : '' ?>><?= htmlspecialchars($vl, ENT_QUOTES, 'UTF-8') ?></option>
                    <?php endforeach; ?>
                  </select>
                  <input type="hidden" name="protocol" value="https">
                  <input type="hidden" name="port" value="443">
                  <input type="hidden" name="notes" value="">
                </div>
              </td>
              <td>
                <div class="airmax-device-stack">
                  <input class="form-control form-control-sm airmax-input" name="username" placeholder="اسم المستخدم">
                  <input class="form-control form-control-sm airmax-input" type="password" name="password" placeholder="كلمة المرور">
                  <div class="airmax-snmp-field" style="display:none">
                    <input class="form-control form-control-sm airmax-input" name="snmp_community" value="public" placeholder="SNMP Community">
                  </div>
                </div>
              </td>
              <td>
                <div class="airmax-config-stack">
                  <input class="form-control form-control-sm airmax-input airmax-sort" type="number" name="sort_order" value="99">
                  <label class="airmax-toggle-wrap">
                    <span>مفعّل</span>
                    <label class="airmax-check"><input type="checkbox" name="is_enabled" value="1" checked><span></span></label>
                  </label>
                </div>
              </td>
              <td class="airmax-probe-cell">
                <div class="airmax-route-text">سيتم تحديد البروتوكول والمنفذ والمسار تلقائياً</div>
                <div class="airmax-vendor-os">اختر الشركة لتسريع الفحص، وMimosa يحتاج REST + SNMP للـ MACات</div>
                <div class="airmax-probe-result">بعد الإضافة شغّل فحص المنفذ لأول مرة</div>
                <span class="badge badge-secondary">بانتظار الحفظ</span>
              </td>
              <td class="airmax-actions-cell">
                <div class="airmax-actions-grid airmax-actions-grid-add">
                  <button class="btn btn-primary btn-sm airmax-icon-action" name="save_device" value="1" title="إضافة" aria-label="إضافة"><i class="fa fa-plus" aria-hidden="true"></i></button>
                </div>
              </td>
          </tr>
        </tbody>
      </table>
    </div>
    </div>

    <div class="airmax-tab-panel <?= $activeTab === 'router-match' ? 'is-active' : '' ?>" data-airmax-panel="router-match" <?= $activeTab === 'router-match' ? '' : 'hidden' ?>>
      <div class="rxr-router-port-card airmax-router-match-card" id="rxrRouterPortCard" aria-label="قراءة منفذ راوتر مخصص">
        <div class="rxr-router-port-head">
          <div>
            <h3>الجلب والمطابقة من راوتر MikroTik</h3>
            <p>اختر الراوتر والمنفذ، ثم احفظ القراءة كمصدر رسمي مستقل يظهر في تقرير المطابقة والداشبورد وصفحة المشتركين باسم المنفذ.</p>
          </div>
          <span class="rxr-router-port-badge">مطابقة منفذ</span>
        </div>
        <div class="rxr-router-port-controls">
          <label>
            <span>الراوتر</span>
            <select id="rxrRouterSelect">
              <option value="">اختر الراوتر...</option>
              <?php foreach ($rxrRouters as $rt): ?>
                <option value="<?= (int)($rt['id'] ?? 0) ?>"><?= htmlspecialchars(($rt['name'] ?? 'Router') . ' - ' . ($rt['host'] ?? '') . ':' . (int)($rt['api_port'] ?? 8728), ENT_QUOTES, 'UTF-8') ?></option>
              <?php endforeach; ?>
            </select>
          </label>
          <label>
            <span>المنفذ</span>
            <select id="rxrInterfaceSelect" disabled>
              <option value="">اختر الراوتر أولاً...</option>
            </select>
          </label>
          <button type="button" class="rxr-btn rxr-btn-primary" id="rxrPortMatchBtn" disabled>جلب ومطابقة المنفذ</button>
        </div>
        <div class="rxr-router-port-status" id="rxrPortStatus">جاهز.</div>
        <div class="rxr-router-port-summary" id="rxrPortSummary" hidden></div>
        <div class="table-responsive rxr-port-table-wrap" id="rxrPortTableWrap" hidden>
          <table class="table table-sm table-bordered rxr-table rxr-port-table">
            <thead>
              <tr>
                <th>MAC</th>
                <th>الحالة</th>
                <th>المشترك</th>
                <th>PPP</th>
                <th>مصدر الهوية</th>
                <th>ملاحظة أمنية</th>
              </tr>
            </thead>
            <tbody id="rxrPortTableBody"></tbody>
          </table>
        </div>
      </div>

      <div class="rxr-router-port-official airmax-router-official">
        <h3>منافذ الراوتر المحفوظة</h3>
        <div class="table-responsive rxr-table-wrap">
          <table class="table table-sm table-bordered rxr-table rxr-table-clean rxr-official-table airmax-router-ports-table">
            <thead>
              <tr>
                <th>#</th>
                <th>اسم المنفذ</th>
                <th>الراوتر / المنفذ</th>
                <th>MAC خام</th>
                <th>MAC منفذ</th>
                <th>إدارة</th>
              </tr>
            </thead>
            <tbody>
            <?php if (!$rxrRouterPortSources): ?>
              <tr><td colspan="6" class="text-center text-muted">لا توجد منافذ راوتر محفوظة بعد.</td></tr>
            <?php else: foreach ($rxrRouterPortSources as $rp): ?>
              <?php $rpKey = (string)($rp['key'] ?? ''); $rpPseudoId = (int)($rp['pseudo_id'] ?? 0); ?>
              <tr>
                <td><span class="rxr-id-badge"><?= $rpPseudoId ?></span></td>
                <td><strong><?= htmlspecialchars((string)($rp['name'] ?? ''), ENT_QUOTES, 'UTF-8') ?></strong></td>
                <td><span><?= htmlspecialchars((string)($rp['router_name'] ?? ''), ENT_QUOTES, 'UTF-8') ?></span><br><small class="ltr-cell"><?= htmlspecialchars((string)($rp['interface_label'] ?? $rp['interface'] ?? ''), ENT_QUOTES, 'UTF-8') ?></small></td>
                <td><span class="rxr-count rxr-count-raw"><?= (int)($rp['raw_count'] ?? 0) ?></span></td>
                <td><span class="rxr-count rxr-count-client"><?= (int)($rp['client_count'] ?? 0) ?></span></td>
                <td class="rxr-port-manage-cell">
                  <button type="button" class="rxr-port-rename-btn" data-key="<?= htmlspecialchars($rpKey, ENT_QUOTES, 'UTF-8') ?>" data-pseudo-id="<?= $rpPseudoId ?>" data-name="<?= htmlspecialchars((string)($rp['name'] ?? ''), ENT_QUOTES, 'UTF-8') ?>" title="تعديل اسم المنفذ" aria-label="تعديل اسم المنفذ"><i class="fa fa-pencil" aria-hidden="true"></i></button>
                  <button type="button" class="rxr-port-remove-btn" data-key="<?= htmlspecialchars($rpKey, ENT_QUOTES, 'UTF-8') ?>" data-pseudo-id="<?= $rpPseudoId ?>" title="إزالة" aria-label="إزالة"><i class="fa fa-trash" aria-hidden="true"></i></button>
                </td>
              </tr>
            <?php endforeach; endif; ?>
            </tbody>
          </table>
        </div>
      </div>
    </div>

    <div class="airmax-tab-panel <?= $activeTab === 'device-log' ? 'is-active' : '' ?>" data-airmax-panel="device-log" <?= $activeTab === 'device-log' ? '' : 'hidden' ?>>
      <section class="airmax-device-log-panel" aria-label="سجل الأجهزة">
        <div class="airmax-device-log-head">
          <div>
            <h3>سجل الأجهزة</h3>
            <p>يعرض هنا آخر اللوجات الحقيقية الناجحة المحفوظة من داخل الجهاز نفسه.</p>
          </div>
          <div class="airmax-device-log-actions">
            <form method="post" class="airmax-device-log-pull-form">
              <input type="hidden" name="open_tab" value="device-log">
              <div class="airmax-device-log-request">
                <div class="airmax-device-log-request__text">
                  <strong>قراءة سجل جهاز</strong>
                  <small>اختر الجهاز المطلوب، ثم ابدأ قراءة الأحداث المحفوظة داخله.</small>
                </div>
                <label class="airmax-device-log-picker">
                  <span>اختر الجهاز</span>
                  <select class="form-control form-control-sm airmax-input" name="device_log_id" aria-label="اختر الجهاز لقراءة سجله" required>
                    <option value="" disabled <?= $selectedDeviceLogId <= 0 ? 'selected' : '' ?>>اختر الجهاز المراد قراءة سجله...</option>
                    <?php foreach ($devices as $dev): ?>
                      <?php
                        $devId = (int)($dev['id'] ?? 0);
                        if ($devId <= 0) continue;
                        $devName = trim((string)($dev['name'] ?? ''));
                        $devHost = trim((string)($dev['host'] ?? ''));
                        $devLabel = ($devName !== '' ? $devName : ('#' . $devId)) . ($devHost !== '' ? ' - ' . $devHost : '');
                      ?>
                      <option value="<?= $devId ?>" <?= $selectedDeviceLogId === $devId ? 'selected' : '' ?>><?= htmlspecialchars($devLabel, ENT_QUOTES, 'UTF-8') ?></option>
                    <?php endforeach; ?>
                  </select>
                </label>
                <button class="btn btn-sm btn-warning" name="pull_device_log" value="1"><i class="fa fa-list-alt" aria-hidden="true"></i> قراءة السجل</button>
              </div>
            </form>
            <div class="airmax-device-log-stats">
              <span>آخر <?= (int)count($deviceLogRows) ?> لوج ناجح محفوظ</span>
              <?php if ($deviceSystemLogCount > 0): ?><span><?= (int)$deviceSystemLogCount ?> حركة نظام مخفية عن هذا العرض</span><?php endif; ?>
            </div>
          </div>
        </div>
        <?php if ($deviceLogLastFailure): ?>
          <?php
            $failDevice = trim((string)($deviceLogLastFailure['device_name'] ?? ''));
            if ($failDevice === '') $failDevice = '#' . (int)($deviceLogLastFailure['device_id'] ?? 0);
            $failRaw = trim((string)($deviceLogLastFailure['raw_event'] ?? ''));
            $failAt = trim((string)($deviceLogLastFailure['event_at'] ?? ''));
          ?>
          <div class="alert alert-warning airmax-device-log-last-error mb-0">
            <strong>آخر محاولة سحب لم تحدّث اللوج المحفوظ:</strong>
            <?= htmlspecialchars($failDevice, ENT_QUOTES, 'UTF-8') ?>
            <?php if ($failAt !== ''): ?><span dir="ltr"><?= htmlspecialchars($failAt, ENT_QUOTES, 'UTF-8') ?></span><?php endif; ?>
            <div><?= htmlspecialchars($failRaw !== '' ? $failRaw : 'لم يتم تسجيل سبب واضح.', ENT_QUOTES, 'UTF-8') ?></div>
            <small>الجدول أدناه يبقى آخر لوج ناجح محفوظ، وليس نتيجة هذه المحاولة الفاشلة.</small>
          </div>
        <?php endif; ?>
      <div class="table-responsive airmax-device-log-wrap" dir="ltr">
        <div class="airmax-device-log-inner" dir="rtl">
        <table class="table table-bordered table-sm airmax-settings-table airmax-device-log-table" dir="rtl">
          <thead>
            <tr>
              <th>الوقت</th>
              <th>الجهاز</th>
              <th>العملية</th>
              <th>الحالة</th>
              <th>آخر لوج ناجح محفوظ</th>
              <th>التفسير والتفاصيل</th>
            </tr>
          </thead>
          <tbody>
          <?php if (!$deviceLogRows): ?>
            <tr><td colspan="6" class="text-center text-muted">لا توجد قراءة محفوظة لسجل الجهاز بعد. اختر جهازاً من الأعلى واضغط قراءة سجل الجهاز.</td></tr>
          <?php else: foreach ($deviceLogRows as $lr): ?>
            <?php
              $logSource = (string)($lr['event_source'] ?? '');
              $rawOriginal = trim((string)($lr['raw_event'] ?? ''));
              $raw = ($logSource === 'device_native_log')
                ? $rawOriginal
                : (function_exists('ua_log_compact') ? ua_log_compact($rawOriginal) : $rawOriginal);
              $translatedRaw = ($logSource === 'device_native_log' && function_exists('ua_device_native_log_translate_lines')) ? ua_device_native_log_translate_lines($raw) : '';
              $summary = trim((string)($lr['arabic_summary'] ?? ''));
              if ($logSource === 'device_native_log' && function_exists('ua_device_log_translate')) $summary = ua_device_log_translate((string)($lr['status'] ?? ''), $raw, $logSource);
              if ($summary === '' && function_exists('ua_device_log_translate')) $summary = ua_device_log_translate((string)($lr['status'] ?? ''), $raw, $logSource);
              $st = strtolower((string)($lr['status'] ?? ''));
              $badge = airmax_device_log_status_class($st);
              $actionText = airmax_device_log_action_text((string)($lr['event_key'] ?? ''), $logSource, $raw);
              $statusText = airmax_device_log_status_text($st);
              $sourceText = airmax_device_log_source_text($logSource);
              $detailsList = airmax_device_log_details($lr);
              $deviceLabel = trim((string)($lr['device_name'] ?? ''));
              if ($deviceLabel === '') $deviceLabel = '#' . (int)($lr['device_id'] ?? 0);
            ?>
            <tr>
              <td dir="ltr"><?= htmlspecialchars((string)($lr['event_at'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td>
              <td>
                <strong><?= htmlspecialchars($deviceLabel, ENT_QUOTES, 'UTF-8') ?></strong>
                <div class="airmax-vendor-os" dir="ltr"><?= htmlspecialchars((string)($lr['host'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
              </td>
              <td>
                <strong><?= htmlspecialchars($actionText, ENT_QUOTES, 'UTF-8') ?></strong>
                <div class="airmax-vendor-os"><?= htmlspecialchars($sourceText, ENT_QUOTES, 'UTF-8') ?></div>
              </td>
              <td><span class="badge badge-<?= htmlspecialchars($badge, ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($statusText, ENT_QUOTES, 'UTF-8') ?></span></td>
              <td>
                <div class="airmax-log-view-stack">
                  <code class="airmax-device-log-raw airmax-log-raw-block" dir="ltr"><?= htmlspecialchars($raw !== '' ? $raw : '—', ENT_QUOTES, 'UTF-8') ?></code>
                  <?php if ($translatedRaw !== ''): ?>
                    <button type="button" class="airmax-log-translate-btn" data-airmax-log-translate>ترجمة</button>
                    <code class="airmax-device-log-raw airmax-log-translated-block" dir="rtl" hidden><?= htmlspecialchars($translatedRaw, ENT_QUOTES, 'UTF-8') ?></code>
                  <?php endif; ?>
                </div>
              </td>
              <td>
                <div class="airmax-device-log-summary"><?= htmlspecialchars($summary !== '' ? $summary : '—', ENT_QUOTES, 'UTF-8') ?></div>
                <?php if ($detailsList): ?>
                  <dl class="airmax-device-log-details">
                    <?php foreach ($detailsList as $pair): ?>
                      <div><dt><?= htmlspecialchars((string)$pair[0], ENT_QUOTES, 'UTF-8') ?></dt><dd><?= htmlspecialchars((string)$pair[1], ENT_QUOTES, 'UTF-8') ?></dd></div>
                    <?php endforeach; ?>
                  </dl>
                <?php endif; ?>
              </td>
            </tr>
          <?php endforeach; endif; ?>
          </tbody>
        </table>
        </div>
      </div>
      </section>
    </div>
  </div>
</div>
</div>
<script>
(function(){
  function esc(v){
    return String(v == null ? '' : v).replace(/[&<>"']/g, function(c){ return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[c]; });
  }

  document.querySelectorAll('tr[data-airmax-form]').forEach(function(row){
    var formId = row.getAttribute('data-airmax-form');
    if(!formId) return;
    row.querySelectorAll('input, select, textarea, button').forEach(function(field){
      if(!field.hasAttribute('form')) field.setAttribute('form', formId);
    });
  });

  document.querySelectorAll('[data-airmax-device-row]').forEach(function(row){
    var toggle = row.querySelector('.airmax-edit-toggle');
    if(!toggle) return;
    toggle.addEventListener('click', function(){
      var editing = row.classList.toggle('is-editing');
      toggle.classList.toggle('is-active', editing);
      toggle.setAttribute('title', editing ? 'إغلاق التعديل' : 'تعديل بيانات الجهاز');
      toggle.setAttribute('aria-label', editing ? 'إغلاق التعديل' : 'تعديل بيانات الجهاز');
      if(editing){
        var field = row.querySelector('input[name="name"]');
        if(field) field.focus({preventScroll:true});
        row.scrollIntoView({block:'nearest', behavior:'smooth'});
      }
    });
  });

  var addNewButton = document.querySelector('[data-airmax-add-new]');
  var newRow = document.querySelector('[data-airmax-new-row]');
  if(addNewButton && newRow){
    addNewButton.addEventListener('click', function(){
      var scroller = newRow.closest('.table-responsive');
      if(scroller) scroller.scrollTop = scroller.scrollHeight;
      window.setTimeout(function(){
        var name = newRow.querySelector('input[name="name"]');
        if(name) name.focus({preventScroll:true});
      }, 280);
    });
  }

  document.querySelectorAll('.airmax-local-tab').forEach(function(tab){
    tab.addEventListener('click', function(){
      var key = tab.getAttribute('data-airmax-tab') || 'devices';
      document.querySelectorAll('.airmax-local-tab').forEach(function(t){ t.classList.toggle('is-active', t === tab); });
      document.querySelectorAll('.airmax-tab-panel').forEach(function(panel){
        var on = (panel.getAttribute('data-airmax-panel') === key);
        panel.hidden = !on;
        panel.classList.toggle('is-active', on);
      });
    });
  });

  document.querySelectorAll('[data-airmax-log-translate]').forEach(function(btn){
    btn.addEventListener('click', function(){
      var wrap = btn.closest('.airmax-log-view-stack');
      var translated = wrap ? wrap.querySelector('.airmax-log-translated-block') : null;
      if (!translated) return;
      var show = translated.hidden;
      translated.hidden = !show;
      btn.classList.toggle('is-active', show);
      btn.textContent = show ? 'إخفاء الترجمة' : 'ترجمة';
    });
  });

  var routerSelect = document.getElementById('rxrRouterSelect');
  var ifaceSelect = document.getElementById('rxrInterfaceSelect');
  var portBtn = document.getElementById('rxrPortMatchBtn');
  var portStatus = document.getElementById('rxrPortStatus');
  var portSummary = document.getElementById('rxrPortSummary');
  var portWrap = document.getElementById('rxrPortTableWrap');
  var portBody = document.getElementById('rxrPortTableBody');

  function ps(text){ if(portStatus) portStatus.textContent = text; }
  function fillInterfaces(list){
    if(!ifaceSelect) return;
    ifaceSelect.innerHTML = '<option value="">اختر المنفذ...</option>';
    (list || []).forEach(function(it){
      var opt = document.createElement('option');
      opt.value = it.name || '';
      opt.textContent = it.label || it.name || '';
      ifaceSelect.appendChild(opt);
    });
    ifaceSelect.disabled = !(list && list.length);
    if(portBtn) portBtn.disabled = true;
  }
  if(routerSelect){
    routerSelect.addEventListener('change', function(){
      var id = routerSelect.value || '';
      fillInterfaces([]);
      if(!id){ ps('اختر الراوتر أولاً.'); return; }
      ps('جارٍ جلب المنافذ من الراوتر...');
      fetch('api/router_port_interfaces.php?router_id=' + encodeURIComponent(id), {headers:{'X-Requested-With':'XMLHttpRequest'}})
        .then(function(r){ return r.json(); })
        .then(function(data){
          if(!data || !data.ok){ throw new Error((data && data.message) || 'تعذر جلب المنافذ'); }
          fillInterfaces(data.interfaces || []);
          ps('تم جلب ' + ((data.interfaces || []).length) + ' منفذ.');
        })
        .catch(function(e){ ps(e && e.message ? e.message : 'تعذر جلب المنافذ.'); });
    });
  }
  if(ifaceSelect){
    ifaceSelect.addEventListener('change', function(){
      if(portBtn) portBtn.disabled = !(routerSelect && routerSelect.value && ifaceSelect.value);
    });
  }
  function renderPortResult(data){
    var s = data.summary || {};
    if(portSummary){
      portSummary.hidden = false;
      portSummary.innerHTML =
        '<span>MAC خام: <b>' + esc(s.raw_mac_total || 0) + '</b></span>' +
        '<span>MAC منفذ: <b>' + esc(s.client_mac_total || 0) + '</b></span>' +
        '<span>MAC معروف: <b>' + esc(s.known_mac_total || 0) + '</b></span>' +
        '<span>مطابق: <b>' + esc(s.matched_total || 0) + '</b></span>' +
        '<span>غير معروف: <b>' + esc(s.unknown_total || 0) + '</b></span>' +
        '<span>تعارض أمني: <b>' + esc(s.conflict_total || 0) + '</b></span>';
    }
    if(portBody){
      portBody.innerHTML = '';
      (data.matched || []).forEach(function(row){
        var tr = document.createElement('tr');
        tr.innerHTML =
          '<td class="ltr-cell">' + esc(row.mac) + '</td>' +
          '<td><span class="rxr-count rxr-count-final">مطابق</span></td>' +
          '<td>' + esc(row.full_name || row.username || '') + '</td>' +
          '<td class="ltr-cell">' + esc(row.ppp_username || row.ppp_user || '') + '</td>' +
          '<td class="ltr-cell small">' + esc(row.mac_source || '') + '</td>' +
          '<td>' + (row.ownership_conflict ? '<span class="rxr-count rxr-count-warn">ملكية تحتاج مراجعة مراقب الشبكة</span>' : '<span class="rxr-muted">—</span>') + '</td>';
        portBody.appendChild(tr);
      });
      (data.unknown || []).forEach(function(mac){
        var tr = document.createElement('tr');
        tr.innerHTML =
          '<td class="ltr-cell">' + esc(mac) + '</td>' +
          '<td><span class="rxr-count rxr-count-muted">غير معروف</span></td>' +
          '<td colspan="4" class="rxr-muted">لا يوجد مشترك مطابق في مصادر الهوية الحالية</td>';
        portBody.appendChild(tr);
      });
    }
    if(portWrap) portWrap.hidden = false;
  }
  if(portBtn){
    portBtn.addEventListener('click', function(){
      if(!routerSelect || !ifaceSelect || !routerSelect.value || !ifaceSelect.value){ ps('اختر الراوتر والمنفذ.'); return; }
      portBtn.disabled = true;
      var old = portBtn.textContent;
      portBtn.textContent = 'جارٍ الجلب...';
      ps('جارٍ قراءة Bridge Host من المنفذ المختار وحفظه ضمن المطابقة الرسمية...');
      var fd = new FormData();
      fd.append('router_id', routerSelect.value);
      fd.append('interface', ifaceSelect.value);
      fetch('api/router_port_match.php', {method:'POST', body:fd, headers:{'X-Requested-With':'XMLHttpRequest'}})
        .then(function(r){ return r.json(); })
        .then(function(data){
          if(!data || !data.ok){ throw new Error((data && data.message) || 'فشل قراءة المنفذ'); }
          renderPortResult(data);
          ps('تمت قراءة المنفذ ' + (data.interface || '') + ' ومطابقته وحفظه. سيتم تحديث الصفحة...');
          setTimeout(function(){ window.location.reload(); }, 900);
        })
        .catch(function(e){ ps(e && e.message ? e.message : 'فشل قراءة المنفذ.'); })
        .finally(function(){ portBtn.disabled = false; portBtn.textContent = old; });
    });
  }

  document.querySelectorAll('.rxr-port-rename-btn').forEach(function(btn){
    btn.addEventListener('click', function(){
      var key = btn.getAttribute('data-key') || '';
      var pseudoId = btn.getAttribute('data-pseudo-id') || '';
      var current = btn.getAttribute('data-name') || '';
      var name = prompt('اسم المنفذ داخل البرنامج:', current);
      if(name === null) return;
      name = String(name || '').replace(/\s+/g, ' ').trim();
      if(!name){ alert('اكتب اسم المنفذ أولاً.'); return; }
      var fd = new FormData();
      fd.append('key', key);
      fd.append('pseudo_id', pseudoId);
      fd.append('name', name);
      btn.disabled = true;
      fetch('api/router_port_rename.php', {method:'POST', body:fd, headers:{'X-Requested-With':'XMLHttpRequest'}})
        .then(function(r){ return r.json(); })
        .then(function(data){
          if(!data || !data.ok){ throw new Error((data && data.message) || 'فشل تعديل اسم المنفذ'); }
          window.location.reload();
        })
        .catch(function(e){ alert(e && e.message ? e.message : 'فشل تعديل اسم المنفذ.'); btn.disabled = false; });
    });
  });

  document.querySelectorAll('.rxr-port-remove-btn').forEach(function(btn){
    btn.addEventListener('click', function(){
      var key = btn.getAttribute('data-key') || '';
      var pseudoId = btn.getAttribute('data-pseudo-id') || '';
      if(!key && !pseudoId){ alert('تعذر تحديد المنفذ.'); return; }
      if(!confirm('إزالة هذا المنفذ من المطابقة الرسمية والداشبورد؟')) return;
      var fd = new FormData();
      fd.append('key', key);
      fd.append('pseudo_id', pseudoId);
      btn.disabled = true;
      fetch('api/router_port_remove.php', {method:'POST', body:fd, headers:{'X-Requested-With':'XMLHttpRequest'}})
        .then(function(r){ return r.json(); })
        .then(function(data){
          if(!data || !data.ok){ throw new Error((data && data.message) || 'فشل إزالة المنفذ'); }
          window.location.reload();
        })
        .catch(function(e){ alert(e && e.message ? e.message : 'فشل إزالة المنفذ.'); btn.disabled = false; });
    });
  });

  function statusMap(status){
    var map = {
      success: ['badge badge-success', 'جاهز'],
      partial: ['badge badge-warning', 'جزئي'],
      failed: ['badge badge-danger', 'فشل'],
      running: ['badge badge-info', 'جارٍ'],
      idle: ['badge badge-secondary', 'معلّق']
    };
    return map[status] || map.idle;
  }

  function setBadge(id, status){
    var badge = document.getElementById('probe-badge-' + id);
    if (!badge) return;
    var item = statusMap(status);
    badge.className = item[0];
    badge.textContent = item[1];
  }

  function setRunning(id, percent, text) {
    var wrap = document.getElementById('progress-wrap-' + id);
    var bar = document.getElementById('progress-bar-' + id);
    var pct = document.getElementById('progress-text-' + id);
    var stage = document.getElementById('progress-stage-' + id);
    var result = document.getElementById('probe-result-' + id);
    if (wrap) wrap.classList.remove('d-none');
    if (bar) bar.style.width = (percent || 0) + '%';
    if (pct) pct.textContent = (percent || 0) + '%';
    if (stage) stage.textContent = text || 'جارٍ الفحص';
    if (result) result.textContent = '';
    setBadge(id, 'running');
  }

  function setResult(id, data) {
    var wrap = document.getElementById('progress-wrap-' + id);
    var result = document.getElementById('probe-result-' + id);
    var route = document.getElementById('route-' + id);
    var meta = document.getElementById('probe-meta-' + id);
    var btn = document.querySelector('.airmax-probe-btn[data-id="' + id + '"]');
    var rebtn = document.querySelector('.airmax-reprobe-btn[data-id="' + id + '"]');
    if (wrap) wrap.classList.add('d-none');
    if (result) result.textContent = data.message || '';
    if (route && data.route && data.route.display) route.textContent = data.route.display;
    if (meta && data.route) {
      var bits = [];
      if (data.route.vendor) bits.push(data.route.vendor);
      if (data.route.os) bits.push(data.route.os);
      if (data.route.mode) bits.push(data.route.mode);
      meta.textContent = bits.join(' | ');
    }
    setBadge(id, data.status || 'idle');
    if (btn) btn.disabled = !!data.locked;
    if (rebtn) rebtn.classList.toggle('d-none', !data.locked);
  }

  function tickProgress(id){
    var percent = 14;
    var stages = ['فحص المنفذ', 'اختبار البروتوكول', 'تحديد الشركة والنظام', 'تجربة الدخول وجلب البيانات'];
    var stageIndex = 0;
    setRunning(id, percent, stages[stageIndex]);
    return setInterval(function(){
      percent = Math.min(88, percent + (percent < 45 ? 10 : 6));
      if (percent > 28) stageIndex = 1;
      if (percent > 52) stageIndex = 2;
      if (percent > 72) stageIndex = 3;
      setRunning(id, percent, stages[stageIndex]);
    }, 700);
  }

  function startProbe(id, force) {
    var timer = tickProgress(id);
    fetch('api/airmax_probe.php?id=' + encodeURIComponent(id) + (force ? '&force=1' : ''), {
      headers: { 'X-Requested-With': 'XMLHttpRequest' }
    })
    .then(function(r){ return r.json(); })
    .then(function(data){ window.clearInterval(timer); setResult(id, data); })
    .catch(function(){ window.clearInterval(timer); setResult(id, {status:'failed', message:'فشل الاتصال بواجهة الفحص', locked:false}); });
  }


  function syncSnmpFields(scope) {
    (scope || document).querySelectorAll('[data-airmax-form]').forEach(function(row){
      var vendor = row.querySelector('select[name="preferred_vendor"]');
      var field = row.querySelector('.airmax-snmp-field');
      if (!vendor || !field) return;
      field.style.display = (vendor.value === 'mimosa') ? '' : 'none';
    });
  }

  document.querySelectorAll('select[name="preferred_vendor"]').forEach(function(sel){
    sel.addEventListener('change', function(){ syncSnmpFields(document); });
  });
  syncSnmpFields(document);

  document.querySelectorAll('.airmax-probe-btn').forEach(function(btn){
    btn.addEventListener('click', function(){ startProbe(this.getAttribute('data-id'), false); });
  });
  document.querySelectorAll('.airmax-reprobe-btn').forEach(function(btn){
    btn.addEventListener('click', function(){ startProbe(this.getAttribute('data-id'), true); });
  });
})();
</script>
<?php if (!UA_EMBED) { echo '</section></div>'; require_once __DIR__ . '/footer.php'; } ?>
