<?php
declare(strict_types=1);

if (!defined('ROZKLAD_ROOT')) {
    define('ROZKLAD_ROOT', dirname(__DIR__));
}
if (!defined('ROZKLAD_STORAGE')) {
    define('ROZKLAD_STORAGE', ROZKLAD_ROOT . '/storage');
}
if (!defined('ROZKLAD_INSTALL_STATE_FILE')) {
    define('ROZKLAD_INSTALL_STATE_FILE', ROZKLAD_STORAGE . '/install/state.php');
}
if (!defined('ROZKLAD_DB_RUNTIME_FILE')) {
    define('ROZKLAD_DB_RUNTIME_FILE', __DIR__ . '/db_runtime.php');
}
if (!defined('ROZKLAD_MAIL_RUNTIME_FILE')) {
    define('ROZKLAD_MAIL_RUNTIME_FILE', __DIR__ . '/mail_runtime.php');
}
if (!defined('ROZKLAD_LICENSE_API_URL')) {
    define('ROZKLAD_LICENSE_API_URL', 'https://sitepro.net.ua/license-center/api/license-hook.php');
}
if (!defined('ROZKLAD_LICENSE_PRODUCT_SLUG')) {
    define('ROZKLAD_LICENSE_PRODUCT_SLUG', 'elektronniy-rozklad');
}
if (!defined('ROZKLAD_LICENSE_SHARED_SECRET')) {
    define('ROZKLAD_LICENSE_SHARED_SECRET', 'CHANGE_ME_STRONG_SHARED_SECRET');
}
if (!defined('ROZKLAD_LICENSE_CACHE_TTL')) {
    define('ROZKLAD_LICENSE_CACHE_TTL', 86400);
}

function rozklad_install_state(): array {
    if (is_file(ROZKLAD_INSTALL_STATE_FILE)) {
        $state = require ROZKLAD_INSTALL_STATE_FILE;
        return is_array($state) ? $state : [];
    }
    return [];
}

function rozklad_save_install_state(array $state): bool {
    $content = "<?php\nreturn " . var_export($state, true) . ";\n";
    $tmp = ROZKLAD_INSTALL_STATE_FILE . '.tmp';
    if (@file_put_contents($tmp, $content, LOCK_EX) === false) {
        return false;
    }
    return @rename($tmp, ROZKLAD_INSTALL_STATE_FILE);
}

function rozklad_is_installed(): bool {
    $state = rozklad_install_state();
    return !empty($state['installed']) && is_file(ROZKLAD_DB_RUNTIME_FILE);
}

function rozklad_mail_config(): array {
    if (is_file(ROZKLAD_MAIL_RUNTIME_FILE)) {
        $cfg = require ROZKLAD_MAIL_RUNTIME_FILE;
        return is_array($cfg) ? $cfg : [];
    }
    return [];
}

function rozklad_mail_configured(): bool {
    $cfg = rozklad_mail_config();
    return !empty($cfg['host']) && !empty($cfg['from_email']);
}

function rozklad_auth_allowed(): bool {
    $state = rozklad_install_state();
    if (!$state) {
        return false;
    }
    return !empty($state['mail_configured']);
}

function rozklad_current_scheme(): string {
    $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443);
    return $https ? 'https' : 'http';
}

function rozklad_current_host(): string {
    return preg_replace('~[^a-z0-9\.-]~i', '', (string)($_SERVER['HTTP_HOST'] ?? 'localhost')) ?: 'localhost';
}

function rozklad_base_url(): string {
    return rozklad_current_scheme() . '://' . rozklad_current_host();
}

function rozklad_server_fingerprint(): string {
    $parts = [
        rozklad_current_host(),
        rozklad_base_url(),
        PHP_OS_FAMILY,
        php_uname('n'),
        $_SERVER['SERVER_ADDR'] ?? '',
        ROZKLAD_ROOT,
    ];
    return hash('sha256', implode('|', $parts));
}

function rozklad_post_json(string $url, array $payload): array {
    $json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    $headers = [
        'Content-Type: application/json',
        'Content-Length: ' . strlen((string)$json),
        'X-License-Secret: ' . ROZKLAD_LICENSE_SHARED_SECRET,
    ];
    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $json,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 8,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
        ]);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $error = curl_error($ch);
        curl_close($ch);
        if ($response === false) {
            return ['ok' => false, 'error' => 'cURL error #' . $errno . ': ' . $error];
        }
        $data = json_decode((string)$response, true);
        return is_array($data) ? $data : ['ok' => false, 'error' => 'Некоректна JSON-відповідь від сервера ліцензій.'];
    }
    $ctx = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => implode("\r\n", $headers) . "\r\n",
            'content' => $json,
            'timeout' => 8,
            'ignore_errors' => true,
        ],
    ]);
    $response = @file_get_contents($url, false, $ctx);
    if ($response === false) {
        return ['ok' => false, 'error' => 'Не вдалося виконати HTTP-запит до сервера ліцензій.'];
    }
    $data = json_decode((string)$response, true);
    return is_array($data) ? $data : ['ok' => false, 'error' => 'Некоректна JSON-відповідь від сервера ліцензій.'];
}

function rozklad_remote_license_check(bool $force = false): array {
    $state = rozklad_install_state();
    if (empty($state['license_key']) || empty($state['install_id'])) {
        return ['ok' => false, 'message' => 'Ліцензія ще не ініціалізована.'];
    }
    if (ROZKLAD_LICENSE_API_URL === '' || ROZKLAD_LICENSE_SHARED_SECRET === 'CHANGE_ME_STRONG_SHARED_SECRET') {
        return ['ok' => true, 'skipped' => true, 'message' => 'Віддалена перевірка ще не налаштована.'];
    }
    $lastCheckTs = empty($state['license_last_remote_check_at']) ? 0 : strtotime((string)$state['license_last_remote_check_at']);
    if (!$force && $lastCheckTs && (time() - $lastCheckTs) < ROZKLAD_LICENSE_CACHE_TTL && !empty($state['license_remote_status']) && in_array((string)$state['license_remote_status'], ['active', 'grace', 'local-fallback'], true)) {
        return ['ok' => true, 'cached' => true, 'message' => 'Використано кеш стану ліцензії.'];
    }

    $payload = [
        'action' => 'heartbeat',
        'product_slug' => ROZKLAD_LICENSE_PRODUCT_SLUG,
        'license_key' => (string)$state['license_key'],
        'install_id' => (string)$state['install_id'],
        'domain' => rozklad_current_host(),
        'base_url' => rozklad_base_url(),
        'fingerprint' => rozklad_server_fingerprint(),
        'php' => PHP_VERSION,
        'time' => gmdate('c'),
    ];
    $response = rozklad_post_json(ROZKLAD_LICENSE_API_URL, $payload);
    $state['license_last_remote_check_at'] = date('c');
    if (!empty($response['ok']) && !empty($response['license_valid'])) {
        $state['license_remote_status'] = (string)($response['license_status'] ?? 'active');
        $state['license_remote_message'] = (string)($response['message'] ?? 'Ліцензію підтверджено.');
        rozklad_save_install_state($state);
        return ['ok' => true, 'message' => $state['license_remote_message']];
    }
    $state['license_remote_status'] = (string)($response['license_status'] ?? 'blocked');
    $state['license_remote_message'] = (string)($response['message'] ?? $response['error'] ?? 'Ліцензія недійсна або заблокована.');
    rozklad_save_install_state($state);
    return ['ok' => false, 'message' => $state['license_remote_message']];
}

function rozklad_require_valid_license(bool $force = false): void {
    $result = rozklad_remote_license_check($force);
    if (!empty($result['ok'])) {
        return;
    }
    http_response_code(403);
    echo '<!doctype html><html lang="uk"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Ліцензію не підтверджено</title><style>body{font-family:system-ui,sans-serif;background:#0f172a;color:#e2e8f0;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:20px}.card{max-width:760px;background:#111827;border:1px solid #334155;border-radius:18px;padding:24px}a{color:#86efac}.muted{color:#93a2b1}</style></head><body><div class="card"><h1>Ліцензію не підтверджено</h1><p>' . htmlspecialchars((string)($result['message'] ?? 'Сервер ліцензій відхилив доступ.'), ENT_QUOTES, 'UTF-8') . '</p><p class="muted">Перевірте ключ, домен і налаштування центру ліцензій на sitepro.net.ua.</p><p><a href="/install.php">Повернутися до install.php</a></p></div></body></html>';
    exit;
}

function rozklad_redirect_to_install_if_needed(): void {
    $script = basename((string)($_SERVER['SCRIPT_NAME'] ?? ''));
    if ($script === 'install.php') {
        return;
    }
    if (!rozklad_is_installed()) {
        header('Location: /install.php');
        exit;
    }
}

function rozklad_require_mail_setup(string $message = 'Пошта ще не налаштована. Завершіть налаштування в install.php.'): void {
    if (rozklad_auth_allowed()) {
        return;
    }
    http_response_code(503);
    echo '<!doctype html><html lang="uk"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Налаштування не завершено</title><style>body{font-family:system-ui,sans-serif;background:#0f172a;color:#e2e8f0;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:20px}.card{max-width:680px;background:#111827;border:1px solid #334155;border-radius:18px;padding:24px}a{color:#86efac}</style></head><body><div class="card"><h1>Налаштування не завершено</h1><p>' . htmlspecialchars($message, ENT_QUOTES, 'UTF-8') . '</p><p><a href="/install.php">Перейти до install.php</a></p></div></body></html>';
    exit;
}
