<?php
declare(strict_types=1);

// Endpoint simple para registrar visitas desde las páginas HTML.
// Se consume desde JS con navigator.sendBeacon()/fetch().

function now_iso(): string { return gmdate('c'); }

function is_https(): bool {
  return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (($_SERVER['SERVER_PORT'] ?? '') === '443');
}

function get_client_ip(): string {
  $xff = (string)($_SERVER['HTTP_X_FORWARDED_FOR'] ?? '');
  if ($xff !== '') {
    $parts = array_map('trim', explode(',', $xff));
    if (!empty($parts[0])) return $parts[0];
  }
  return (string)($_SERVER['REMOTE_ADDR'] ?? '');
}

function read_salt(string $path): string {
  if (is_file($path)) {
    $s = trim((string)@file_get_contents($path));
    if ($s !== '') return $s;
  }
  $salt = bin2hex(random_bytes(16));
  @file_put_contents($path, $salt . "\n", LOCK_EX);
  return $salt;
}

function hash_str(string $salt, string $v): string {
  if ($v === '') return '';
  return hash('sha256', $salt . '|' . $v);
}

function get_or_set_vid(): string {
  $vid = (string)($_COOKIE['tb_vid'] ?? '');
  if ($vid === '' || strlen($vid) < 16) {
    $vid = bin2hex(random_bytes(12));
    setcookie('tb_vid', $vid, [
      'expires' => time() + (180 * 24 * 60 * 60),
      'path' => '/',
      'secure' => is_https(),
      'httponly' => true,
      'samesite' => 'Lax',
    ]);
  }
  return $vid;
}

function no_cache(): void {
  header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
  header('Pragma: no-cache');
  header('Expires: 0');
}

function respond(int $code): void {
  http_response_code($code);
  no_cache();
  exit;
}

$method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
if ($method !== 'POST' && $method !== 'GET') respond(405);

$p = (string)($_REQUEST['p'] ?? '');
$r = (string)($_REQUEST['r'] ?? '');
$t = (string)($_REQUEST['t'] ?? '');

if (strlen($p) > 500) $p = substr($p, 0, 500);
if (strlen($r) > 800) $r = substr($r, 0, 800);
if (strlen($t) > 200) $t = substr($t, 0, 200);

// Evita registrar el admin y el propio tracker.
if (stripos($p, 'admin.php') !== false || stripos($p, 'track.php') !== false) respond(204);

$salt = read_salt(__DIR__ . '/visits_salt.txt');
$vid = get_or_set_vid();
$ua = (string)($_SERVER['HTTP_USER_AGENT'] ?? '');
$ip = get_client_ip();

$event = [
  'ts' => now_iso(),
  'vid' => $vid,
  'p' => $p,
  'r' => $r,
  't' => $t,
  // Guardamos hashes (no IP/User-Agent en claro).
  'ip' => hash_str($salt, $ip),
  'ua' => hash_str($salt, $ua),
];

$line = json_encode($event, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
if (is_string($line) && $line !== '') {
  @file_put_contents(__DIR__ . '/visits.jsonl', $line . "\n", FILE_APPEND | LOCK_EX);
}

respond(204);

