<?php

declare(strict_types=1);

namespace App\Core;

final class RequestTrace
{
    private static $enabled = false;
    private static $requestId = '';
    private static $startedAt = 0.0;
    private static $marks = [];
    private static $durations = [];
    private static $context = [];

    public static function start(float $startedAt, string $page): void
    {
        self::$enabled = ($page === 'revenue');
        if (!self::$enabled) return;
        self::$startedAt = $startedAt;
        self::$requestId = date('Ymd_His') . '_' . substr(bin2hex(random_bytes(6)), 0, 12);
        self::$marks['request_start'] = $startedAt;
        self::$context = ['page'=>$page, 'method'=>($_SERVER['REQUEST_METHOD'] ?? 'GET'), 'uri'=>($_SERVER['REQUEST_URI'] ?? '')];
    }

    public static function enabled(): bool { return self::$enabled; }
    public static function id(): string { return self::$requestId; }
    public static function mark(string $name): void { if (self::$enabled) self::$marks[$name] = microtime(true); }
    public static function begin(string $name): void { if (self::$enabled) self::$marks[$name . ':begin'] = microtime(true); }
    public static function end(string $name): void
    {
        if (!self::$enabled) return;
        $key=$name.':begin'; $start=self::$marks[$key] ?? null;
        if (is_float($start)) self::$durations[$name]=round((microtime(true)-$start)*1000,2);
    }
    public static function add(string $name, float $ms): void { if (self::$enabled) self::$durations[$name]=round($ms,2); }
    public static function context(string $key, $value): void { if (self::$enabled) self::$context[$key]=$value; }

    public static function snapshot(bool $final=false): array
    {
        $now=microtime(true);
        $dur=self::$durations;
        $dur['php_request_total']=round(($now-self::$startedAt)*1000,2);
        return [
            'schema'=>'DDB_REVENUE_END_TO_END_TRACE_V1',
            'request_id'=>self::$requestId,
            'captured_at'=>date(DATE_ATOM),
            'final'=>$final,
            'durations_ms'=>$dur,
            'context'=>self::$context,
            'memory_peak_mb'=>round(memory_get_peak_usage(true)/1048576,2),
        ];
    }

    public static function emitHeaders(): void
    {
        if (!self::$enabled || headers_sent()) return;
        $snapshot=self::snapshot(); $parts=[];
        foreach ($snapshot['durations_ms'] as $name=>$ms) {
            $safe=preg_replace('/[^A-Za-z0-9_-]/','_', (string)$name);
            $parts[]=$safe.';dur='.number_format((float)$ms,2,'.','');
        }
        header('Server-Timing: '.implode(', ', $parts));
        header('X-DDB-Request-ID: '.self::$requestId);
        header('Timing-Allow-Origin: *');
    }

    public static function browserConfig(): array
    {
        return ['request_id'=>self::$requestId, 'server'=>self::snapshot(), 'beacon_url'=>'index.php?page=revenue-performance-beacon&lang='.(function_exists('current_lang')?\current_lang():'en')];
    }

    public static function saveBrowserPayload(array $payload): string
    {
        $dir=\storage_path('evidence/revenue-trace');
        if (!is_dir($dir) && !mkdir($dir,0775,true) && !is_dir($dir)) throw new \RuntimeException('Cannot create revenue trace evidence directory.');
        $rid=preg_replace('/[^A-Za-z0-9_-]/','_', (string)($payload['request_id'] ?? 'unknown'));
        $file=$dir.'/REVENUE_END_TO_END_TRACE_'.$rid.'.json';
        $payload['received_at']=date(DATE_ATOM);
        file_put_contents($file, json_encode($payload, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), LOCK_EX);
        file_put_contents($dir.'/LATEST.json', json_encode(['request_id'=>$rid,'file'=>basename($file),'received_at'=>date(DATE_ATOM)], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOCK_EX);
        return $file;
    }
}
