<?php
require_once __DIR__ . '/../auth.php';
if (function_exists('require_login')) require_login('login.php');
require_once __DIR__ . '/../db_bootstrap.php';
require_once __DIR__ . '/../mikrotik_lib.php';
header('Content-Type: application/json; charset=utf-8');
if (function_exists('ensure_db')) ensure_db(true);
$conn = $GLOBALS['conn'] ?? null;
if (!($conn instanceof mysqli)) { http_response_code(500); echo json_encode(['ok'=>false,'message'=>'فشل الاتصال بقاعدة البيانات'], JSON_UNESCAPED_UNICODE); exit; }
function json_exit(array $payload, int $status = 200): void { http_response_code($status); echo json_encode($payload, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); exit; }
function mt_api_call($api, string $path, array $params = []) { if (method_exists($api, 'command')) { $arr = [$path]; foreach ($params as $k => $v) $arr[] = '=' . $k . '=' . $v; return $api->command($arr); } if (method_exists($api, 'comm')) return $api->comm($path, $params); throw new RuntimeException('MikroTik API methods are not available'); }
function parse_time_ms($value): ?float { $value = trim((string)$value); if ($value==='') return null; if (preg_match('/^([0-9]+(?:\.[0-9]+)?)\s*ms$/i',$value,$m)) return (float)$m[1]; if (preg_match('/^([0-9]+(?:\.[0-9]+)?)\s*s$/i',$value,$m)) return (float)$m[1]*1000.0; if (preg_match('/^([0-9]+(?:\.[0-9]+)?)\s*us$/i',$value,$m)) return (float)$m[1]/1000.0; if (is_numeric($value)) return (float)$value; return null; }
function classify_quality(float $avgMs, float $lossPercent): string { if ($lossPercent >= 25 || $avgMs >= 180) return 'سيء'; if ($lossPercent >= 10 || $avgMs >= 100) return 'متوسط'; if ($lossPercent >= 3 || $avgMs >= 60) return 'جيد'; if ($lossPercent > 0 || $avgMs >= 30) return 'جيد جداً'; return 'ممتاز'; }
function ping_target($api, string $target): array {
  $rows = mt_api_call($api, '/ping', ['address'=>$target,'count'=>'5','interval'=>'00:00:00.2','size'=>'56']);
  $sent=0; $received=0; $times=[]; $lossPercent=null; $avgMs=null;
  if (is_array($rows)) foreach ($rows as $row) {
    if (!is_array($row)) continue;
    if (isset($row['packet-loss'])) $lossPercent=(float)str_replace('%','',(string)$row['packet-loss']);
    foreach (['avg-rtt','avg','average-rtt'] as $k) if (isset($row[$k])) { $tmp=parse_time_ms((string)$row[$k]); if($tmp!==null) $avgMs=$tmp; }
    $hasSeq = array_key_exists('seq',$row)||array_key_exists('host',$row)||array_key_exists('time',$row)||array_key_exists('status',$row);
    if($hasSeq) $sent++;
    $status=strtolower(trim((string)($row['status'] ?? '')));
    $timeMs=parse_time_ms((string)($row['time'] ?? ''));
    if($timeMs!==null && ($status==='' || !in_array($status,['timeout','timed out','host unreachable','unreachable'],true))){ $received++; $times[]=$timeMs; }
  }
  if($sent<=0) $sent=5;
  if($avgMs===null && $times) $avgMs=array_sum($times)/count($times);
  if($lossPercent===null) $lossPercent=$sent>0?max(0,(($sent-$received)/$sent)*100.0):100.0;
  if($avgMs===null) $avgMs=999.0;
  return ['target'=>$target,'avg_ms'=>round($avgMs,1),'loss_percent'=>round($lossPercent,1),'quality'=>classify_quality($avgMs,$lossPercent)];
}
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id <= 0) json_exit(['ok'=>false,'message'=>'معرف المشترك غير صالح'],400);
$rs = $conn->query("SELECT id, username, full_name, ppp_username, ip_address, is_online FROM subscribers WHERE id={$id} LIMIT 1");
if (!$rs || !$rs->num_rows) json_exit(['ok'=>false,'message'=>'المشترك غير موجود'],404);
$sub = $rs->fetch_assoc();
$pppUser = trim((string)($sub['ppp_username'] ?? '')); if ($pppUser === '') $pppUser = trim((string)($sub['username'] ?? ''));
$storedIp = trim((string)($sub['ip_address'] ?? ''));
$api = mt_api_connect($conn);
if (!$api) json_exit(['ok'=>false,'message'=>(string)($GLOBALS['mt_last_error'] ?? 'فشل الاتصال بـ MikroTik')],500);
try {
  $activeRows = mt_api_call($api, '/ppp/active/print', []);
  $activeRow = null;
  if (is_array($activeRows)) foreach ($activeRows as $row) { if (!is_array($row)) continue; $name = trim((string)($row['name'] ?? $row['user'] ?? '')); if ($name !== '' && $name === $pppUser) { $activeRow = $row; break; } }
  if (!$activeRow) json_exit(['ok'=>true,'online'=>false,'status_text'=>'غير متصل','message'=>'المشترك غير متصل حالياً']);
  $targets=[]; $pppIp = trim((string)($activeRow['address'] ?? '')); if($pppIp!=='') $targets[]=$pppIp; if($storedIp!=='' && !in_array($storedIp,$targets,true)) $targets[]=$storedIp;
  if(!$targets) json_exit(['ok'=>false,'online'=>true,'message'=>'تعذر تحديد IP للمشترك المتصل'],500);
  $results=[]; foreach($targets as $t) $results[] = ping_target($api, $t);
  usort($results, function($a,$b){ return ($a['loss_percent'] <=> $b['loss_percent']) ?: ($a['avg_ms'] <=> $b['avg_ms']); });
  $best = $results[0];
  json_exit(['ok'=>true,'online'=>true,'status_text'=>$best['quality'],'avg_ms'=>$best['avg_ms'],'loss_percent'=>$best['loss_percent'],'target_ip'=>$best['target'],'ppp_username'=>$pppUser,'tested_targets'=>array_column($results,'target'),'message'=>'تم فحص الجودة بنجاح']);
} catch (Throwable $e) {
  json_exit(['ok'=>false,'message'=>'فشل فحص الجودة: '.$e->getMessage()],500);
} finally {
  if (is_object($api) && method_exists($api, 'disconnect')) { try { $api->disconnect(); } catch (Throwable $e) {} }
}
