<?php

require_once dirname(__DIR__) . '/db_bootstrap.php';
require_once dirname(__DIR__) . '/agent_service.php';
require_once dirname(__DIR__) . '/install_link_lib.php';

function mobile_test_request(string $url, string $instanceId, string $key, array $payload = [], bool $valid = true): array {
  $body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: '{}';
  $timestamp = time();
  $nonce = bin2hex(random_bytes(18));
  $signature = hash_hmac('sha256', $timestamp . '.' . $nonce . '.' . $body, $valid ? $key : 'invalid-key');
  $http_response_header = [];
  $context = stream_context_create(['http'=>[
    'method'=>'POST',
    'header'=>implode("\r\n", [
      'Content-Type: application/json', 'Accept: application/json',
      'X-UA-Instance: ' . $instanceId,
      'X-UA-Timestamp: ' . $timestamp,
      'X-UA-Nonce: ' . $nonce,
      'X-UA-Signature: ' . $signature,
    ]),
    'content'=>$body, 'ignore_errors'=>true, 'timeout'=>15,
  ]]);
  $raw = (string)@file_get_contents($url, false, $context);
  if (substr($raw, 0, 3) === "\xEF\xBB\xBF") $raw = substr($raw, 3);
  $status = 0;
  if ($http_response_header && preg_match('/\s(\d{3})\s/', $http_response_header[0], $m)) $status = (int)$m[1];
  return ['status'=>$status, 'body'=>json_decode($raw, true) ?: [], 'raw'=>$raw];
}

$conn = ensure_db(true);
ua_agent_schema_migrate($conn);
ua_link_ensure_schema($conn);
$base = $argv[1] ?? 'http://127.0.0.1:8080/mikrotik/admin/api/mobile';
$suffix = bin2hex(random_bytes(5));
$agentInstance = 'mobile_agent_' . $suffix;
$branchInstance = 'mobile_branch_' . $suffix;
$agentKey = hash('sha256', 'agent-secret-' . $suffix);
$branchKey = hash('sha256', 'branch-secret-' . $suffix);
$agentId = 0;
$exitCode = 0;

try {
  foreach ([[$agentInstance, 'Mobile Agent Test', 'agent', $agentKey], [$branchInstance, 'Mobile Branch Test', 'branch', $branchKey]] as $link) {
    [$id, $name, $type, $key] = $link;
    $status = 'approved';
    $stmt = $conn->prepare("INSERT INTO ua_link_requests (instance_id,instance_name,install_type,request_secret_hash,status,approved_at,created_at,updated_at) VALUES (?,?,?,?,?,NOW(),NOW(),NOW())");
    $stmt->bind_param('sssss', $id, $name, $type, $key, $status);
    if (!$stmt->execute()) throw new RuntimeException($stmt->error);
    $stmt->close();
  }
  $saved = ua_agent_repo_save($conn, [
    'code'=>'MOB-' . strtoupper($suffix), 'full_name'=>'Mobile API Test Agent',
    'username'=>'mobile_' . $suffix, 'linked_instance_id'=>$agentInstance,
    'is_active'=>1, 'portal_enabled'=>1, 'pos_enabled'=>1,
  ]);
  if (empty($saved['ok'])) throw new RuntimeException((string)$saved['error']);
  $agentId = (int)$saved['id'];

  $checks = [];
  foreach ([['agent', $agentInstance, $agentKey], ['branch', $branchInstance, $branchKey]] as $role) {
    [$name, $instance, $key] = $role;
    foreach ([
      ['dashboard', []], ['subscribers', ['query'=>'']], ['transactions', []],
    ] as $endpoint) {
      $response = mobile_test_request($base . '/' . $endpoint[0] . '.php', $instance, $key, $endpoint[1]);
      if ($response['status'] !== 200 || empty($response['body']['ok'])) {
        throw new RuntimeException("{$name}/{$endpoint[0]} failed: " . json_encode($response, JSON_UNESCAPED_UNICODE));
      }
      $checks[$name . '_' . $endpoint[0]] = $response['status'];
    }
  }
  $bad = mobile_test_request($base . '/dashboard.php', $branchInstance, $branchKey, [], false);
  if ($bad['status'] !== 401 || ($bad['body']['error'] ?? '') !== 'INVALID_SIGNATURE') {
    throw new RuntimeException('Invalid signature was not rejected.');
  }
  $invalidPay = mobile_test_request($base . '/invoice_pay.php', $branchInstance, $branchKey, ['invoice_id'=>0, 'request_id'=>'mobile-test-request']);
  if ($invalidPay['status'] !== 422 || ($invalidPay['body']['error'] ?? '') !== 'INVALID_PAYMENT_REQUEST') {
    throw new RuntimeException('Payment validation failed: ' . json_encode($invalidPay, JSON_UNESCAPED_UNICODE));
  }
  $checks['invalid_signature'] = 401;
  $checks['payment_validation'] = 422;
  echo json_encode(['ok'=>true, 'checks'=>$checks], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . PHP_EOL;
} catch (Throwable $e) {
  fwrite(STDERR, $e->getMessage() . PHP_EOL);
  $exitCode = 1;
} finally {
  foreach ([$agentInstance, $branchInstance] as $instance) {
    $esc = $conn->real_escape_string($instance);
    @$conn->query("DELETE FROM agent_sync_nonces WHERE instance_id='{$esc}'");
    @$conn->query("DELETE FROM ua_link_requests WHERE instance_id='{$esc}'");
  }
  if ($agentId > 0) {
    @$conn->query("DELETE FROM agent_activity_log WHERE agent_id={$agentId}");
    @$conn->query("DELETE FROM agent_sync_events WHERE agent_id={$agentId}");
    @$conn->query("DELETE FROM agent_ledger_entries WHERE agent_id={$agentId}");
    @$conn->query("DELETE FROM agents WHERE id={$agentId}");
  }
}
exit($exitCode);

