<?php
// api/config.php
declare(strict_types=1);

// 🔐 Schimbă asta cu un secret lung (32+)
const API_KEY = 'SCHIMBA_CU_UN_SECRET_LUNG_AICI';

// ✅ Baza workerului
const WORKER_BASE = '/home4/etimpuls/audit_worker/app';
const QUEUE_DIR   = WORKER_BASE . '/queue';
const OUTPUTS_DIR = WORKER_BASE . '/outputs';

// DEMO rules
const DEMO_MAX_PAGES = 50;
const DEMO_LIMIT_SECONDS = 24 * 60 * 60;

// FULL rules (ajusteaza dupa server)
const FULL_MAX_PAGES = 10000;          // sau 5000 daca vrei
const FULL_LIMIT_SECONDS = 60 * 60;   // 1 ora (anti-blocaj)

// FULL only
const FULL_DEFAULT_MAX_PAGES = 500;   // default pentru UI
const FULL_HARD_MAX_PAGES    = 5000;  // cap absolut (siguranță)

// Throttling (adaptat la serverul tău)
const FULL_MAX_RUNNING_JOBS  = 12;    // câte joburi simultan (egal cu #workeri sau puțin sub)
const FULL_MAX_PENDING_JOBS  = 300;   // coadă acceptată



// Schimba cu ceva al tau (orice text lung), ca sa nu poata ghici fingerprint-ul
const FP_SALT = 'SCHIMBA_AICI_CU_UN_SALT_LUNG_UNIC_2025';

// Folder rate limit (fisiere lock)
const RATE_LIMIT_DIR = OUTPUTS_DIR . '/ratelimit';

// Dacă ai WP pe alt subdomeniu și vrei CORS, pune domeniul tău aici.
// Ex: https://etimpulseo.ro
const ALLOW_ORIGIN = '*'; // sau 'https://etimpulseo.ro'

function cors_headers(): void {
    header('Access-Control-Allow-Origin: ' . ALLOW_ORIGIN);
    header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, X-API-Key');
}

function respond(array $data, int $code = 200): void {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function require_auth(): void {
    $key = $_SERVER['HTTP_X_API_KEY'] ?? ($_GET['key'] ?? '');
    if (!$key || !hash_equals(API_KEY, (string)$key)) {
        respond(['ok' => false, 'error' => 'Unauthorized'], 401);
    }
}

function get_client_ip(): string {
    $candidates = [
        $_SERVER['HTTP_CF_CONNECTING_IP'] ?? null,
        $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null,
        $_SERVER['HTTP_X_REAL_IP'] ?? null,
        $_SERVER['REMOTE_ADDR'] ?? null,
    ];
    foreach ($candidates as $ip) {
        if (!$ip) continue;
        $ip = trim(explode(',', (string)$ip)[0]);
        if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
    }
    return '0.0.0.0';
}

function ensure_dirs(): void {
    $dirs = [
        QUEUE_DIR,
        QUEUE_DIR . '/pending',
        QUEUE_DIR . '/running',
        QUEUE_DIR . '/done',
        QUEUE_DIR . '/failed',
        OUTPUTS_DIR,
        OUTPUTS_DIR . '/xlsx',
        RATE_LIMIT_DIR,
    ];
    foreach ($dirs as $d) {
        if (!is_dir($d)) @mkdir($d, 0755, true);
    }
}

function normalize_url(string $url): string {
    $url = trim($url);
    if ($url === '') return '';
    if (!preg_match('~^https?://~i', $url)) $url = 'https://' . $url;
    return $url;
}

function is_valid_url(string $url): bool {
    if (!filter_var($url, FILTER_VALIDATE_URL)) return false;
    $parts = parse_url($url);
    if (!$parts || empty($parts['host'])) return false;
    $scheme = strtolower($parts['scheme'] ?? '');
    return in_array($scheme, ['http', 'https'], true);
}

function make_job_id(): string {
    return bin2hex(random_bytes(12));
}

function get_or_set_fp_cookie(): string {
    $name = 'etseo_fp';
    if (!empty($_COOKIE[$name])) return (string)$_COOKIE[$name];

    $val = bin2hex(random_bytes(16));
    // 30 zile
    setcookie($name, $val, time() + 30*24*60*60, '/', '', true, true);
    $_COOKIE[$name] = $val;
    return $val;
}

function demo_fingerprint_hash(): string {
    $ua = (string)($_SERVER['HTTP_USER_AGENT'] ?? '');
    $al = (string)($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '');
    $fp = get_or_set_fp_cookie();
    return hash('sha256', $fp . '|' . $ua . '|' . $al . '|' . FP_SALT);
}

function rate_limit_demo_or_die(): void {
    $hash = demo_fingerprint_hash();
    $lock = RATE_LIMIT_DIR . '/demo_' . $hash . '.json';

    if (file_exists($lock)) {
        $data = json_decode((string)@file_get_contents($lock), true);
        $last = (int)($data['ts'] ?? 0);
        if ($last > 0 && (time() - $last) < DEMO_LIMIT_SECONDS) {
            $remain = DEMO_LIMIT_SECONDS - (time() - $last);
            respond([
                'ok' => false,
                'error' => 'LIMIT_DEMO_24H',
                'message' => 'Ai rulat deja DEMO. Mai incearca dupa ce expira perioada de 24h.',
                'retry_after_sec' => $remain,
            ], 429);
        }
    }
    // nu scriem lock aici, il scriem DUPA ce cream jobul (in submit_demo.php)
}

function write_demo_lock(string $job_id): void {
    $hash = demo_fingerprint_hash();
    $lock = RATE_LIMIT_DIR . '/demo_' . $hash . '.json';
    @file_put_contents($lock, json_encode([
        'ts' => time(),
        'job_id' => $job_id,
        'ip' => get_client_ip(),
    ], JSON_UNESCAPED_SLASHES));
}

function queue_write_pending(string $job_id, array $job): string {
    $path = QUEUE_DIR . '/pending/' . $job_id . '.json';
    $json = json_encode($job, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if ($json === false) {
        throw new RuntimeException('JSON encode failed');
    }
    if (@file_put_contents($path, $json) === false) {
        throw new RuntimeException('Cannot write job file to pending');
    }
    @chmod($path, 0664);
    return $path;
}

function find_job_state(string $job_id): array {
    $paths = [
        'pending' => QUEUE_DIR . '/pending/' . $job_id . '.json',
        'running' => QUEUE_DIR . '/running/' . $job_id . '.json',
        'done'    => QUEUE_DIR . '/done/' . $job_id . '.json',
        'failed'  => QUEUE_DIR . '/failed/' . $job_id . '.json',
    ];
    foreach ($paths as $state => $p) {
        if (file_exists($p)) return ['state' => $state, 'path' => $p];
    }
    return ['state' => 'missing', 'path' => ''];
}
