<?php

ob_start();
require_once dirname(__DIR__, 2) . '/db_bootstrap.php';
require_once dirname(__DIR__, 2) . '/agent_service.php';
require_once dirname(__DIR__, 2) . '/install_link_lib.php';
if (ob_get_length()) ob_clean();

header('Content-Type: application/json; charset=utf-8');
$conn = ensure_db(true);
ua_agent_schema_migrate($conn);
ua_link_ensure_schema($conn);

function agent_sync_reply(int $status, array $data): void {
  http_response_code($status);
  echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  exit;
}

function agent_sync_header(string $name): string {
  $key = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
  return trim((string)($_SERVER[$key] ?? ''));
}

function agent_sync_authenticate(mysqli $conn): array {
  $raw = file_get_contents('php://input');
  $instanceId = preg_replace('/[^a-zA-Z0-9_-]/', '', agent_sync_header('X-UA-Instance')) ?? '';
  $timestamp = (int)agent_sync_header('X-UA-Timestamp');
  $nonce = substr(agent_sync_header('X-UA-Nonce'), 0, 120);
  $signature = strtolower(agent_sync_header('X-UA-Signature'));
  if ($instanceId === '' || $timestamp <= 0 || $nonce === '' || !preg_match('/^[a-f0-9]{64}$/', $signature)) {
    agent_sync_reply(401, ['ok'=>false,'error'=>'INVALID_AUTH_HEADERS']);
  }
  if (abs(time() - $timestamp) > 300) {
    agent_sync_reply(401, ['ok'=>false,'error'=>'STALE_REQUEST']);
  }

  $instanceEsc = $conn->real_escape_string($instanceId);
  $linkRs = @$conn->query("SELECT * FROM ua_link_requests WHERE instance_id='{$instanceEsc}' AND install_type='agent' AND status='approved' LIMIT 1");
  if (!$linkRs || !$linkRs->num_rows) {
    agent_sync_reply(403, ['ok'=>false,'error'=>'INSTANCE_NOT_APPROVED']);
  }
  $link = $linkRs->fetch_assoc();
  $key = strtolower(trim((string)$link['request_secret_hash']));
  $expected = hash_hmac('sha256', $timestamp . '.' . $nonce . '.' . $raw, $key);
  if (!hash_equals($expected, $signature)) {
    agent_sync_reply(401, ['ok'=>false,'error'=>'INVALID_SIGNATURE']);
  }

  $nonceStmt = $conn->prepare("INSERT INTO agent_sync_nonces (instance_id,nonce,request_timestamp) VALUES (?,?,?)");
  if (!$nonceStmt) agent_sync_reply(500, ['ok'=>false,'error'=>'NONCE_STORE_FAILED']);
  $nonceStmt->bind_param('ssi', $instanceId, $nonce, $timestamp);
  try {
    $nonceStored = $nonceStmt->execute();
  } catch (Throwable $e) {
    $nonceStored = false;
  }
  if (!$nonceStored) {
    $nonceStmt->close();
    agent_sync_reply(409, ['ok'=>false,'error'=>'REPLAYED_REQUEST']);
  }
  $nonceStmt->close();
  @$conn->query("DELETE FROM agent_sync_nonces WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 DAY)");
  @$conn->query("UPDATE ua_link_requests SET last_seen_at=NOW(),updated_at=NOW() WHERE instance_id='{$instanceEsc}'");

  $agentRs = @$conn->query("SELECT * FROM agents WHERE linked_instance_id='{$instanceEsc}' AND archived_at IS NULL LIMIT 1");
  if (!$agentRs || !$agentRs->num_rows) {
    agent_sync_reply(409, ['ok'=>false,'error'=>'INSTANCE_NOT_LINKED_TO_AGENT']);
  }
  $payload = json_decode($raw, true);
  if (!is_array($payload)) $payload = [];
  return ['raw'=>$raw,'payload'=>$payload,'instance_id'=>$instanceId,'agent'=>$agentRs->fetch_assoc()];
}
