<?php
declare(strict_types=1);

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');

$analyticsFile = __DIR__ . '/analytics.json';

function send_json(int $status, array $payload): void
{
    http_response_code($status);
    echo json_encode($payload);
    exit;
}

function ensure_store_file(string $path): void
{
    if (!file_exists($path)) {
        $seed = [
            'totals' => [
                'visits' => 0,
                'sessionsCompleted' => 0,
                'durationSec' => 0,
            ],
            'visitors' => new stdClass(),
            'pages' => new stdClass(),
            'sessions' => new stdClass(),
        ];
        file_put_contents($path, json_encode($seed, JSON_PRETTY_PRINT) . "\n", LOCK_EX);
    }
}

function read_store(string $path): array
{
    ensure_store_file($path);
    $raw = file_get_contents($path);
    $data = json_decode($raw ?: '{}', true);

    if (!is_array($data)) {
        $data = [];
    }

    $data['totals'] = is_array($data['totals'] ?? null) ? $data['totals'] : [];
    $data['totals']['visits'] = (int) ($data['totals']['visits'] ?? 0);
    $data['totals']['sessionsCompleted'] = (int) ($data['totals']['sessionsCompleted'] ?? 0);
    $data['totals']['durationSec'] = (int) ($data['totals']['durationSec'] ?? 0);
    $data['visitors'] = is_array($data['visitors'] ?? null) ? $data['visitors'] : [];
    $data['pages'] = is_array($data['pages'] ?? null) ? $data['pages'] : [];
    $data['sessions'] = is_array($data['sessions'] ?? null) ? $data['sessions'] : [];

    return $data;
}

function sanitize_id($value, int $maxLen = 80): string
{
    $value = preg_replace('/[^a-z0-9_-]/i', '', (string) ($value ?? '')) ?? '';
    return substr($value, 0, $maxLen);
}

function sanitize_path($value): string
{
    $value = (string) ($value ?? '/');
    if ($value === '') {
        return '/';
    }
    return substr($value, 0, 160);
}

function save_store(string $path, array $data): void
{
    file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT) . "\n", LOCK_EX);
}

function get_summary(array $data): array
{
    $uniqueVisitors = count($data['visitors']);
    $sessionsCompleted = max(0, (int) ($data['totals']['sessionsCompleted'] ?? 0));
    $avgDurationSec = $sessionsCompleted > 0
        ? (int) round(((int) ($data['totals']['durationSec'] ?? 0)) / $sessionsCompleted)
        : 0;

    $pages = [];
    foreach ($data['pages'] as $path => $page) {
        $visits = (int) ($page['visits'] ?? 0);
        $pageSessions = (int) ($page['sessionsCompleted'] ?? 0);
        $pageDuration = (int) ($page['durationSec'] ?? 0);
        $pages[] = [
            'path' => (string) $path,
            'visits' => $visits,
            'sessionsCompleted' => $pageSessions,
            'avgDurationSec' => $pageSessions > 0 ? (int) round($pageDuration / $pageSessions) : 0,
        ];
    }

    usort($pages, static function (array $a, array $b): int {
        return $b['visits'] <=> $a['visits'];
    });

    return [
        'totals' => [
            'visits' => (int) ($data['totals']['visits'] ?? 0),
            'uniqueVisitors' => $uniqueVisitors,
            'sessionsCompleted' => $sessionsCompleted,
            'avgDurationSec' => $avgDurationSec,
            'activeSessions' => count($data['sessions']),
        ],
        'topPages' => array_slice($pages, 0, 10),
        'updatedAt' => gmdate('c'),
    ];
}

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

if ($method === 'GET') {
    $store = read_store($analyticsFile);
    send_json(200, get_summary($store));
}

if ($method !== 'POST') {
    send_json(405, ['error' => 'Method not allowed.']);
}

$rawBody = file_get_contents('php://input');
$payload = json_decode($rawBody ?: '{}', true);
if (!is_array($payload)) {
    send_json(400, ['error' => 'Invalid JSON payload.']);
}

$type = (string) ($payload['type'] ?? '');
$sessionId = sanitize_id($payload['sessionId'] ?? '');
$visitorId = sanitize_id($payload['visitorId'] ?? '');
$path = sanitize_path($payload['path'] ?? '/');
$now = gmdate('c');

if ($sessionId === '' || $visitorId === '') {
    send_json(400, ['error' => 'sessionId and visitorId are required.']);
}

$store = read_store($analyticsFile);

if (!isset($store['visitors'][$visitorId]) || !is_array($store['visitors'][$visitorId])) {
    $store['visitors'][$visitorId] = [
        'firstSeen' => $now,
        'lastSeen' => $now,
        'visits' => 0,
        'totalDurationSec' => 0,
    ];
}

if (!isset($store['pages'][$path]) || !is_array($store['pages'][$path])) {
    $store['pages'][$path] = [
        'visits' => 0,
        'sessionsCompleted' => 0,
        'durationSec' => 0,
    ];
}

$store['visitors'][$visitorId]['lastSeen'] = $now;

if ($type === 'visit_start') {
    $store['totals']['visits'] += 1;
    $store['visitors'][$visitorId]['visits'] += 1;
    $store['pages'][$path]['visits'] += 1;
    $store['sessions'][$sessionId] = [
        'visitorId' => $visitorId,
        'path' => $path,
        'startedAt' => $now,
    ];
    save_store($analyticsFile, $store);
    send_json(201, ['ok' => true]);
}

if ($type === 'visit_end') {
    $durationSec = (int) ($payload['durationSec'] ?? 0);
    if ($durationSec < 0) {
        $durationSec = 0;
    }
    if ($durationSec > 86400) {
        $durationSec = 86400;
    }

    $session = is_array($store['sessions'][$sessionId] ?? null) ? $store['sessions'][$sessionId] : null;
    if ($session) {
        $sessionPath = sanitize_path($session['path'] ?? $path);
        if (!isset($store['pages'][$sessionPath]) || !is_array($store['pages'][$sessionPath])) {
            $store['pages'][$sessionPath] = [
                'visits' => 0,
                'sessionsCompleted' => 0,
                'durationSec' => 0,
            ];
        }

        $store['totals']['sessionsCompleted'] += 1;
        $store['totals']['durationSec'] += $durationSec;
        $store['pages'][$sessionPath]['sessionsCompleted'] += 1;
        $store['pages'][$sessionPath]['durationSec'] += $durationSec;

        $sessionVisitorId = sanitize_id($session['visitorId'] ?? $visitorId);
        if ($sessionVisitorId !== '' && isset($store['visitors'][$sessionVisitorId])) {
            $store['visitors'][$sessionVisitorId]['totalDurationSec'] += $durationSec;
            $store['visitors'][$sessionVisitorId]['lastSeen'] = $now;
        }

        unset($store['sessions'][$sessionId]);
    }

    save_store($analyticsFile, $store);
    send_json(200, ['ok' => true]);
}

send_json(400, ['error' => 'Unsupported analytics event type.']);
