<?php
// Shared runtime and UI helpers for the agent-facing portal.

require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/security.php';
require_once __DIR__ . '/db_bootstrap.php';
require_once __DIR__ . '/app_assets.php';
require_once __DIR__ . '/app_runtime.php';
require_once __DIR__ . '/media_assets_lib.php';
require_once __DIR__ . '/install_link_lib.php';
require_once __DIR__ . '/agent_lib.php';
require_once __DIR__ . '/agent_runtime_lib.php';
require_once __DIR__ . '/subscriber_view_data_lib.php';

if (!function_exists('agent_portal_ensure_schema')) {
  function agent_portal_ensure_schema(mysqli $conn): void {
    ua_agent_ensure_tables($conn);
    if (table_exists($conn, 'subscribers')) {
      if (!col_exists($conn, 'subscribers', 'agent_status_protected')) {
        @$conn->query("ALTER TABLE subscribers ADD COLUMN agent_status_protected TINYINT(1) NOT NULL DEFAULT 0");
      }
      if (!col_exists($conn, 'subscribers', 'agent_status_password_hash')) {
        @$conn->query("ALTER TABLE subscribers ADD COLUMN agent_status_password_hash VARCHAR(255) NULL");
      }
      if (!col_exists($conn, 'subscribers', 'created_by_type')) {
        @$conn->query("ALTER TABLE subscribers ADD COLUMN created_by_type VARCHAR(30) NULL");
      }
      if (!col_exists($conn, 'subscribers', 'created_by_id')) {
        @$conn->query("ALTER TABLE subscribers ADD COLUMN created_by_id INT NULL");
      }
      if (!col_exists($conn, 'subscribers', 'source_instance_id')) {
        @$conn->query("ALTER TABLE subscribers ADD COLUMN source_instance_id VARCHAR(80) NULL");
      }
    }
  }
}

if (!function_exists('agent_portal_col')) {
  function agent_portal_col(mysqli $conn, string $table, string $col, string $alias = ''): string {
    $alias = $alias !== '' ? $alias : $col;
    if (col_exists($conn, $table, $col)) return "`{$col}` AS `{$alias}`";
    return "'' AS `{$alias}`";
  }
}

if (!function_exists('agent_portal_company')) {
  function agent_portal_company(mysqli $conn): array {
    $companyName = 'بوابة المعتمد';
    $ownerName = '';
    $phone = '';
    $address = '';
    $logoPath = '';
    if (table_exists($conn, 'company_info')) {
      $logoCol = col_exists($conn, 'company_info', 'logo_path') ? ',logo_path' : '';
      $phoneCol = col_exists($conn, 'company_info', 'phone') ? ',phone' : '';
      $addressCol = col_exists($conn, 'company_info', 'address') ? ',address' : '';
      $companyRs = @$conn->query("SELECT company_name,owner_name{$phoneCol}{$addressCol}{$logoCol} FROM company_info WHERE id=1 LIMIT 1");
      if ($companyRs && ($companyRow = $companyRs->fetch_assoc())) {
        $companyName = trim((string)($companyRow['company_name'] ?? '')) ?: $companyName;
        $ownerName = trim((string)($companyRow['owner_name'] ?? ''));
        $phone = trim((string)($companyRow['phone'] ?? ''));
        $address = trim((string)($companyRow['address'] ?? ''));
        $logoPath = trim((string)($companyRow['logo_path'] ?? ''));
      }
    }
    $programLogo = function_exists('ua_media_url') ? ua_media_url('sidebar_program_logo', 'assets/img/sidebar_program_logo.png') : 'assets/img/sidebar_program_logo.png';
    $logoUrl = agent_portal_logo_url($logoPath, $programLogo);
    return ['company_name'=>$companyName, 'owner_name'=>$ownerName, 'phone'=>$phone, 'address'=>$address, 'logo_path'=>$logoPath, 'logo_url'=>$logoUrl];
  }
}

if (!function_exists('agent_portal_logo_url')) {
  function agent_portal_logo_url(string $logoPath, string $fallback): string {
    $logoPath = trim($logoPath);
    if ($logoPath === '') return $fallback;
    if (preg_match('~^https?://~i', $logoPath)) return $logoPath;
    $clean = ltrim(str_replace('\\', '/', $logoPath), '/');
    $abs = __DIR__ . '/' . $clean;
    if (is_file($abs)) {
      $v = (int)@filemtime($abs);
      return $clean . (strpos($clean, '?') === false ? '?v=' : '&v=') . ($v ?: time());
    }
    return $fallback;
  }
}

if (!function_exists('agent_portal_fetch_agents')) {
  function agent_portal_fetch_agents(mysqli $conn): array {
    $rows = [];
    $res = @$conn->query("SELECT id, name, username, phone, balance, balance_cached, is_active, pos_enabled, portal_enabled FROM agents ORDER BY id DESC");
    if ($res) {
      while ($r = $res->fetch_assoc()) {
        if ((int)($r['is_active'] ?? 1) !== 1) continue;
        if ((int)($r['portal_enabled'] ?? 1) !== 1) continue;
        $rows[] = $r;
      }
    }
    return $rows;
  }
}

if (!function_exists('agent_portal_touch_connection')) {
  /**
   * A successfully authenticated portal request is itself an authoritative
   * connectivity heartbeat. Keeping this in the shared bootstrap prevents
   * every agent page from inventing a different online/offline rule.
   */
  function agent_portal_touch_connection(mysqli $conn, ?array $agent): void {
    $instanceId = trim((string)($agent['linked_instance_id'] ?? ''));
    if ($instanceId === '' || !table_exists($conn, 'ua_link_requests')) return;

    $stmt = $conn->prepare(
      "UPDATE ua_link_requests
          SET last_seen_at=NOW(), updated_at=NOW()
        WHERE instance_id=? AND status='approved'
        LIMIT 1"
    );
    if (!$stmt) return;
    $stmt->bind_param('s', $instanceId);
    @$stmt->execute();
    $stmt->close();
  }
}

if (!function_exists('agent_portal_boot')) {
  function agent_portal_boot(mysqli $conn): array {
    if (session_status() === PHP_SESSION_NONE) session_start();
    agent_portal_ensure_schema($conn);
    $forceSelection = !ua_is_agent_install() && (string)($_GET['select'] ?? '') === '1';
    if ($forceSelection) unset($_SESSION['agent_portal_last_agent']);
    $requestedAgentId = $forceSelection
      ? 0
      : (int)($_GET['agent'] ?? $_POST['agent'] ?? ($_SESSION['agent_portal_last_agent'] ?? 0));
    $agentId = ua_agent_portal_resolve_id($conn, $requestedAgentId);
    $agent = $agentId > 0 ? ua_agent_get($conn, $agentId) : null;
    if ($agentId > 0) $_SESSION['agent_portal_last_agent'] = $agentId;
    $sessionKey = $agentId > 0 ? ('agent_portal_' . $agentId) : '';
    $logged = $sessionKey !== '' && !empty($_SESSION[$sessionKey]);
    if ($logged && $agent) {
      agent_portal_touch_connection($conn, $agent);
    }
    return [
      'agent_id'=>$agentId,
      'agent'=>$agent,
      'session_key'=>$sessionKey,
      'logged'=>$logged,
      'company'=>agent_portal_company($conn),
    ];
  }
}

if (!function_exists('agent_portal_connection_state')) {
  function agent_portal_connection_state(mysqli $conn, ?array $agent): array {
    $instanceId = trim((string)($agent['linked_instance_id'] ?? ''));
    $mode = ua_install_type();
    $state = [
      'connected'=>false,
      'label'=>'غير مرتبط بالسيرفر',
      'detail'=>'لا توجد نسخة معتمد مرتبطة بالسيرفر لهذا الحساب.',
      'class'=>'is-offline',
      'instance_id'=>$instanceId,
    ];
    if ($mode === 'agent') {
      $link = ua_install_link_config();
      $linkedInstanceId = trim((string)($link['instance_id'] ?? $instanceId));
      if ($linkedInstanceId === '') return $state;
      $approved = ua_install_link_approved();
      return [
        'connected'=>$approved,
        'label'=>$approved ? 'متصل' : 'غير متصل',
        'detail'=>$approved ? ('السيرفر: ' . $linkedInstanceId) : 'الربط موجود لكن الاتصال غير مؤكد حاليا.',
        'class'=>$approved ? 'is-online' : 'is-warn',
        'instance_id'=>$linkedInstanceId,
      ];
    }
    if ($instanceId === '') return $state;
    if (!table_exists($conn, 'ua_link_requests')) {
      $state['label'] = 'غير متصل';
      $state['detail'] = 'لا يوجد سجل نبض اتصال لهذا السيرفر.';
      $state['class'] = 'is-warn';
      return $state;
    }
    $idEsc = $conn->real_escape_string($instanceId);
    $rs = @$conn->query("SELECT status,last_seen_at FROM ua_link_requests WHERE instance_id='{$idEsc}' LIMIT 1");
    if (!$rs || !$rs->num_rows) {
      $state['label'] = 'غير متصل';
      $state['detail'] = 'لم يتم العثور على نبض اتصال من السيرفر المرتبط.';
      $state['class'] = 'is-warn';
      return $state;
    }
    $row = $rs->fetch_assoc();
    $status = strtolower(trim((string)($row['status'] ?? '')));
    $lastSeen = trim((string)($row['last_seen_at'] ?? ''));
    $fresh = false;
    if ($lastSeen !== '') {
      $ts = strtotime($lastSeen);
      $fresh = $ts !== false && (time() - $ts) <= 600;
    }
    $connected = $status === 'approved' && ($fresh || $lastSeen === '');
    return [
      'connected'=>$connected,
      'label'=>$connected ? 'متصل' : 'غير متصل',
      'detail'=>$lastSeen !== '' ? ('آخر اتصال: ' . $lastSeen) : ('حالة الربط: ' . ($status ?: 'غير معروف')),
      'class'=>$connected ? 'is-online' : 'is-warn',
      'instance_id'=>$instanceId,
    ];
  }
}

if (!function_exists('agent_portal_customer_name')) {
  function agent_portal_customer_name(array $sub): string {
    $parts = [];
    foreach (['first_name', 'father_name', 'last_name'] as $k) {
      $v = trim((string)($sub[$k] ?? ''));
      if ($v !== '') $parts[] = $v;
    }
    $name = trim((string)($sub['full_name'] ?? ''));
    if ($name === '' && $parts) $name = implode(' ', $parts);
    return $name !== '' ? $name : ('#' . (int)($sub['id'] ?? 0));
  }
}

if (!function_exists('agent_portal_search_subscribers')) {
  function agent_portal_search_subscribers(mysqli $conn, string $term, int $limit = 20): array {
    $term = trim($term);
    $termLen = function_exists('mb_strlen') ? mb_strlen($term, 'UTF-8') : strlen($term);
    if ($term === '' || (!ctype_digit($term) && $termLen < 2) || !table_exists($conn, 'subscribers')) return [];
    $searchCols = [];
    foreach (['full_name', 'first_name', 'father_name', 'last_name', 'phone', 'username', 'ppp_username'] as $col) {
      if (col_exists($conn, 'subscribers', $col)) $searchCols[] = $col;
    }
    if (!$searchCols) return [];
    $cols = ['s.id'];
    foreach (['full_name','first_name','father_name','last_name','phone','status','package_name','speed_name','ppp_username','created_by_type','created_by_id','agent_status_protected'] as $col) {
      $cols[] = col_exists($conn, 'subscribers', $col) ? "s.`{$col}` AS `{$col}`" : "'' AS `{$col}`";
    }
    $like = '%' . $conn->real_escape_string($term) . '%';
    $where = [];
    if (ctype_digit($term)) $where[] = 's.id=' . (int)$term;
    foreach ($searchCols as $col) $where[] = "s.`{$col}` LIKE '{$like}'";
    $activeSql = col_exists($conn, 'subscribers', 'is_deleted') ? 'COALESCE(s.is_deleted,0)=0' : '1=1';
    $limit = max(1, min(50, $limit));
    $orderCol = col_exists($conn, 'subscribers', 'full_name') ? 's.full_name ASC,' : '';
    $sql = 'SELECT ' . implode(',', $cols) . " FROM subscribers s WHERE {$activeSql} AND (" . implode(' OR ', $where) . ") ORDER BY {$orderCol} s.id DESC LIMIT {$limit}";
    $rows = [];
    $res = @$conn->query($sql);
    if ($res) while ($r = $res->fetch_assoc()) $rows[] = $r;
    return $rows;
  }
}

if (!function_exists('agent_portal_protected_ok')) {
  function agent_portal_protected_ok(array $row, string $password): bool {
    if (empty($row['agent_status_protected'])) return true;
    $hash = trim((string)($row['agent_status_password_hash'] ?? ''));
    return $hash !== '' && password_verify(trim($password), $hash);
  }
}

if (!function_exists('agent_portal_subscriber_state_label')) {
  function agent_portal_subscriber_state_label(array $row, array $runtime): array {
    if (!empty($runtime['is_online'])) return ['متصل حالياً', 'is-online', 'يوجد اتصال PPPoE نشط لهذا المشترك.'];
    if (!empty($runtime['is_disabled'])) {
      $reason = trim((string)($row['mt_last_disconnect_reason'] ?? $row['last_disconnect_reason'] ?? ''));
      $financial = false;
      foreach (['مالي','فاتورة','unpaid','payment','billing'] as $needle) {
        if ($reason !== '' && stripos($reason, $needle) !== false) $financial = true;
      }
      $manual = !empty($row['ppp_cut_by']) || !empty($row['cut_by']) || (stripos($reason, 'manual') !== false) || (function_exists('mb_stripos') && mb_stripos($reason, 'يدوي') !== false);
      if ($financial) return ['مفصول آلياً بسبب مالي', 'is-danger', $reason ?: 'يظهر أن الفصل مرتبط بالمستحقات أو الفواتير.'];
      if ($manual) return ['مفصول يدوياً', 'is-danger', $reason ?: 'تم تعطيل حساب PPPoE يدوياً.'];
      return ['مفصول', 'is-danger', $reason ?: 'حساب PPPoE معطل أو غير متصل.'];
    }
    return ['غير متصل', 'is-warn', 'لا توجد جلسة PPPoE نشطة حالياً.'];
  }
}

if (!function_exists('agent_portal_render_head')) {
  function agent_portal_render_head(string $title = 'واجهة المعتمد', array $extraCss = [], string $bodyClass = ''): void {
    $portalCssVersion = @filemtime(__DIR__ . '/assets/css/ua_agent_portal.css') ?: time();
    if ((string)($_GET['workspace'] ?? '') === '1') {
      $bodyClass = trim($bodyClass . ' ap-workspace-body');
    }
    $bodyClass = trim($bodyClass);
    ?><!doctype html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title><?= h($title) ?></title>
  <?= ua_asset_tag_css('bootstrap_533_rtl_css') . "\n" ?>
  <?= ua_asset_tag_css('fontawesome_470_css') . "\n" ?>
  <link rel="stylesheet" href="assets/css/ua_agent_portal.css?v=<?= (int)$portalCssVersion ?>">
  <link rel="stylesheet" href="<?= h(ua_asset_versioned_local('assets/css/ua_number_wheel.css')) ?>">
  <script defer src="<?= h(ua_asset_versioned_local('assets/js/ua_number_wheel.js')) ?>"></script>
  <?php foreach($extraCss as $css): $css=(string)$css; if($css==='')continue; $cssPath=__DIR__ . '/' . ltrim($css,'/'); $cssVersion=@filemtime($cssPath) ?: time(); ?><link rel="stylesheet" href="<?= h($css) ?>?v=<?= (int)$cssVersion ?>"><?php endforeach; ?>
</head>
<body<?= $bodyClass !== '' ? ' class="' . h($bodyClass) . '"' : '' ?>>
<?php
  }
}

if (!function_exists('agent_portal_render_public_entry_start')) {
  function agent_portal_render_public_entry_start(string $title, string $subtitle, string $ariaLabel = ''): void {
    $ariaLabel = $ariaLabel !== '' ? $ariaLabel : $title;
    $visual = 'assets/img/login_network_light_bg.png';
    ?>
<section class="exa-login-page ua-public-entry-page ap-public-entry" aria-label="<?= h($ariaLabel) ?>">
  <div class="exa-login-window" role="group" aria-labelledby="agentEntryTitle">
    <div class="exa-login-shell">
      <aside class="exa-login-visual exa-login-visual-full" aria-label="خلفية إدارة الشبكة">
        <img class="exa-visual-image" src="<?= h($visual) ?>" alt="" aria-hidden="true">
        <div class="exa-visual-video-overlay" aria-hidden="true"></div>
        <div class="exa-visual-lock" aria-hidden="true">
          <span class="exa-lock-ring exa-lock-ring-1"></span>
          <span class="exa-lock-ring exa-lock-ring-2"></span>
          <span class="exa-lock-spark exa-lock-spark-1"></span>
          <span class="exa-lock-spark exa-lock-spark-2"></span>
          <span class="exa-lock-shackle"></span>
          <span class="exa-lock-body"><i></i></span>
        </div>
      </aside>
      <section class="exa-login-panel" aria-label="<?= h($ariaLabel) ?>">
        <div class="exa-login-panel-inner">
          <div class="exa-login-copy">
            <h2 id="agentEntryTitle" class="exa-login-title"><?= h($title) ?></h2>
            <p class="exa-login-subtitle"><?= h($subtitle) ?></p>
          </div>
    <?php
  }
}

if (!function_exists('agent_portal_render_public_entry_end')) {
  function agent_portal_render_public_entry_end(): void {
    ?>
        </div>
      </section>
    </div>
  </div>
</section>
    <?php
  }
}

if (!function_exists('agent_portal_render_shell_start')) {
  function agent_portal_render_shell_start(mysqli $conn, array $ctx, string $active = 'home'): void {
    $agent = $ctx['agent'] ?? null;
    $company = $ctx['company'] ?? ['company_name'=>'بوابة المعتمد','owner_name'=>'','logo_url'=>''];
    $GLOBALS['agent_portal_footer_company'] = is_array($company) ? $company : [];
    $connState = agent_portal_connection_state($conn, is_array($agent) ? $agent : null);
    $agentId = (int)($ctx['agent_id'] ?? 0);
    if (empty($ctx['logged'])) {
      $GLOBALS['agent_portal_shell_mode'] = 'public';
      return;
    }
    if ((string)($_GET['workspace'] ?? '') === '1') {
      $GLOBALS['agent_portal_shell_mode'] = 'workspace';
      ?>
<main class="ap-workspace-document">
  <div class="ap-workspace-document__inner">
<?php
      return;
    }
    $GLOBALS['agent_portal_shell_mode'] = 'portal';
    ?>
<main class="ap-shell">
  <div class="ap-container">
    <header class="ap-hero">
      <div class="ap-brand">
        <?php if(!empty($company['logo_url'])): ?>
          <div class="ap-brand-mark ap-brand-logo"><img src="<?= h((string)$company['logo_url']) ?>" alt="<?= h((string)($company['company_name'] ?? 'لوغو البرنامج')) ?>"></div>
        <?php else: ?>
          <div class="ap-brand-mark"><?= h(function_exists('mb_substr') ? mb_substr((string)$company['company_name'],0,1,'UTF-8') : substr((string)$company['company_name'],0,1)) ?></div>
        <?php endif; ?>
        <div>
          <h1><?= h($company['company_name'] ?? 'بوابة المعتمد') ?></h1>
          <p>واجهة المعتمد</p>
        </div>
      </div>
      <div class="ap-hero-tools">
        <div class="ap-link-badge <?= h($connState['class']) ?>">
          <span></span>
          <div><strong><?= h($connState['label']) ?></strong><small><?= h($connState['detail']) ?></small></div>
        </div>
        <?php if($agent && !empty($ctx['logged'])): ?>
          <?php if($active !== 'home'): ?>
            <a class="ap-icon-btn ap-home-btn" href="agent_portal.php?agent=<?= (int)$agentId ?>" title="العودة إلى الواجهة الرئيسية" aria-label="العودة إلى الواجهة الرئيسية"><i class="fa fa-home"></i></a>
          <?php endif; ?>
          <form method="post" action="agent_portal.php" class="m-0">
            <?php ua_csrf_field(); ?>
            <input type="hidden" name="agent" value="<?= (int)$agentId ?>">
            <button class="ap-icon-btn ap-danger" name="logout" title="خروج" aria-label="خروج"><i class="fa fa-sign-out"></i></button>
          </form>
        <?php endif; ?>
      </div>
    </header>
<?php
  }
}

if (!function_exists('agent_portal_render_shell_end')) {
  function agent_portal_render_shell_end(): void {
    $shellMode = (string)($GLOBALS['agent_portal_shell_mode'] ?? 'portal');
    if ($shellMode === 'public') {
      ?>
<?= ua_asset_tag_js('bootstrap_533_bundle_js') . "\n" ?>
</body>
</html>
<?php
      unset($GLOBALS['agent_portal_shell_mode']);
      return;
    }
    if ($shellMode === 'workspace') {
      ?>
  </div>
</main>
<?= ua_asset_tag_js('bootstrap_533_bundle_js') . "\n" ?>
</body>
</html>
<?php
      unset($GLOBALS['agent_portal_shell_mode']);
      return;
    }
    ?>
  </div>
  <?php
    $company = [];
    if (isset($GLOBALS['agent_portal_footer_company']) && is_array($GLOBALS['agent_portal_footer_company'])) {
      $company = $GLOBALS['agent_portal_footer_company'];
    }
    $owner = trim((string)($company['owner_name'] ?? ''));
    $phone = trim((string)($company['phone'] ?? ''));
    $address = trim((string)($company['address'] ?? ''));
    $name = trim((string)($company['company_name'] ?? ''));
  ?>
  <div class="ap-owner-help" tabindex="0" aria-label="معلومات مالك البرنامج">
    <button type="button">?</button>
    <div class="ap-owner-popover">
      <strong>معلومات المالك</strong>
      <?php if($owner !== ''): ?><span>المالك: <?= h($owner) ?></span><?php endif; ?>
      <?php if($name !== ''): ?><span>البرنامج: <?= h($name) ?></span><?php endif; ?>
      <?php if($phone !== ''): ?><span>الهاتف: <?= h($phone) ?></span><?php endif; ?>
      <?php if($address !== ''): ?><span>العنوان: <?= h($address) ?></span><?php endif; ?>
    </div>
  </div>
</main>
<?= ua_asset_tag_js('bootstrap_533_bundle_js') . "\n" ?>
</body>
</html>
<?php
    unset($GLOBALS['agent_portal_shell_mode']);
  }
}
