<?php
/* ============================================================
   log.php - Appends one row per visit to visits.csv.

   Called by js/analytics.js on page load. Captures easily
   available request details. IP / User-Agent / Referer come from
   the request itself; the client also sends the true external
   referrer and a few screen hints in the POST body.

   The CSV lives next to this file. A .htaccess denies public
   download of visits.csv (it contains IP addresses).
   ============================================================ */

header('Content-Type: application/json');
// same-origin only; no caching
header('Cache-Control: no-store');

$csv = __DIR__ . '/visits.csv';

/* ---- gather request details ---- */
function client_ip() {
    // honour common proxy headers, fall back to REMOTE_ADDR
    $keys = ['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'REMOTE_ADDR'];
    foreach ($keys as $k) {
        if (!empty($_SERVER[$k])) {
            $val = $_SERVER[$k];
            if ($k === 'HTTP_X_FORWARDED_FOR') {      // may be a list
                $parts = explode(',', $val);
                $val = trim($parts[0]);
            }
            return $val;
        }
    }
    return '';
}

$ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';

/* external referrer: prefer the value the client read from document.referrer,
   fall back to the HTTP Referer header. */
$ref = isset($_POST['ref']) ? $_POST['ref'] : (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
$page = isset($_POST['page']) ? $_POST['page'] : '';
$screen = isset($_POST['screen']) ? $_POST['screen'] : '';
$lang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';

/* ---- derive browser + version and device type from the UA ---- */
function parse_browser($ua) {
    $b = 'Unknown'; $v = '';
    $checks = [
        ['Edg',      'Edge'],
        ['OPR',      'Opera'],
        ['Opera',    'Opera'],
        ['SamsungBrowser', 'Samsung Internet'],
        ['Firefox',  'Firefox'],
        ['Chrome',   'Chrome'],
        ['Version',  'Safari'],   // Safari reports Version/x.y ... Safari
        ['Safari',   'Safari'],
        ['MSIE',     'IE'],
        ['Trident',  'IE'],
    ];
    foreach ($checks as $c) {
        if (stripos($ua, $c[0]) !== false) {
            $b = $c[1];
            if (preg_match('#' . preg_quote($c[0], '#') . '[/ ]?([0-9\.]+)#i', $ua, $m)) {
                $v = $m[1];
            }
            break;
        }
    }
    return trim($b . ' ' . $v);
}

function parse_device($ua) {
    if (preg_match('/iPad|Tablet|PlayBook|Silk|(Android(?!.*Mobile))/i', $ua)) return 'Tablet';
    if (preg_match('/Mobile|iPhone|iPod|Android.*Mobile|Windows Phone|BlackBerry|IEMobile|Opera Mini/i', $ua)) return 'Mobile';
    if ($ua === '') return 'Unknown';
    return 'Desktop';
}

$row = [
    date('Y-m-d H:i:s'),      // server date/time
    client_ip(),
    parse_browser($ua),
    parse_device($ua),
    $ref,
    $page,
    $screen,
    substr($lang, 0, 32),
    $ua,
];

/* ---- append to CSV with a header on first write ---- */
$header = ['datetime', 'ip', 'browser', 'device', 'referrer', 'page', 'screen', 'language', 'user_agent'];
$needHeader = !file_exists($csv) || filesize($csv) === 0;

$fh = @fopen($csv, 'a');
if ($fh === false) {
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'cannot open log']);
    exit;
}
if (flock($fh, LOCK_EX)) {
    if ($needHeader) fputcsv($fh, $header);
    fputcsv($fh, $row);
    fflush($fh);
    flock($fh, LOCK_UN);
}
fclose($fh);

echo json_encode(['ok' => true]);
