<?php
declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

define('APP_ROOT', dirname(__DIR__));
define('DATA_DIR', APP_ROOT . '/data');
define('LOG_DIR', APP_ROOT . '/logs');
define('CACHE_DIR', APP_ROOT . '/cache');
define('SECURE_CONFIG_DIR', APP_ROOT . '/secure-config');

function data_path(string $file): string {
    return DATA_DIR . '/' . $file;
}

function read_json(string $file, $default = []) {
    $path = data_path($file);
    if (!file_exists($path)) {
        return $default;
    }
    $raw = file_get_contents($path);
    if ($raw === false || $raw === '') {
        return $default;
    }
    $decoded = json_decode($raw, true);
    return is_array($decoded) ? $decoded : $default;
}

function write_json(string $file, $data): bool {
    $path = data_path($file);
    return file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), LOCK_EX) !== false;
}

function get_settings(): array {
    return read_json('settings.json', []);
}

function save_settings(array $settings): bool {
    return write_json('settings.json', $settings);
}

function log_event(string $message): void {
    if (!is_dir(LOG_DIR)) {
        @mkdir(LOG_DIR, 0775, true);
    }
    $line = '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL;
    @file_put_contents(LOG_DIR . '/events.log', $line, FILE_APPEND | LOCK_EX);
}

function require_admin(): void {
    if (empty($_SESSION['admin_logged_in'])) {
        header('Location: login.php');
        exit;
    }
}

function admin_login(string $username, string $password): bool {
    $settings = get_settings();
    $storedUser = $settings['admin_username'] ?? 'admin';
    $storedHash = $settings['admin_password_hash'] ?? '';
    if ($storedHash === '') {
        $storedHash = password_hash('admin', PASSWORD_DEFAULT);
        $settings['admin_password_hash'] = $storedHash;
        save_settings($settings);
    }
    if ($username === $storedUser && password_verify($password, $storedHash)) {
        $_SESSION['admin_logged_in'] = true;
        $_SESSION['admin_username'] = $username;
        return true;
    }
    return false;
}

function admin_logout(): void {
    $_SESSION = [];
    if (ini_get('session.use_cookies')) {
        $params = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], (bool) $params['secure'], (bool) $params['httponly']);
    }
    session_destroy();
}

function get_stations(): array {
    $stations = read_json('stations.json', []);
    if (!empty($stations)) {
        return $stations;
    }
    $settings = get_settings();
    return $settings['stations'] ?? [];
}

function save_stations(array $stations): bool {
    return write_json('stations.json', array_values($stations));
}

function get_schedule(): array {
    return read_json('schedule.json', []);
}

function save_schedule(array $rows): bool {
    return write_json('schedule.json', array_values($rows));
}

function get_clues(): array {
    return read_json('clues.json', []);
}

function save_clues(array $clues): bool {
    return write_json('clues.json', array_values($clues));
}

function get_answers(): array {
    return read_json('answers.json', []);
}

function save_answers(array $answers): bool {
    return write_json('answers.json', array_values($answers));
}

function current_answer_record(): ?array {
    $answers = get_answers();
    foreach ($answers as $answer) {
        if (!empty($answer['active'])) {
            return $answer;
        }
    }
    return $answers[0] ?? null;
}

function answer_matches(string $submitted, array $answerRecord): bool {
    $submitted = mb_strtolower(trim($submitted));
    if ($submitted === '') {
        return false;
    }
    $valid = [];
    if (!empty($answerRecord['answer'])) {
        $valid[] = mb_strtolower(trim((string) $answerRecord['answer']));
    }
    if (!empty($answerRecord['variants']) && is_array($answerRecord['variants'])) {
        foreach ($answerRecord['variants'] as $variant) {
            $variant = mb_strtolower(trim((string) $variant));
            if ($variant !== '') {
                $valid[] = $variant;
            }
        }
    }
    $valid = array_values(array_unique(array_filter($valid)));
    return in_array($submitted, $valid, true);
}

function can_submit(array $settings): bool {
    if (!empty($settings['manual_override'])) {
        return true;
    }
    if (($settings['site_status'] ?? 'live') !== 'live') {
        return false;
    }
    if (empty($settings['submissions_enabled'])) {
        return false;
    }
    if (!empty($settings['timer_enabled']) && !empty($settings['timer_start']) && !empty($settings['timer_duration'])) {
        return (time() < ((int) $settings['timer_start'] + (int) $settings['timer_duration']));
    }
    return true;
}

function time_remaining(array $settings): int {
    if (empty($settings['timer_enabled']) || empty($settings['timer_start']) || empty($settings['timer_duration'])) {
        return 0;
    }
    $end = (int) $settings['timer_start'] + (int) $settings['timer_duration'];
    return max(0, $end - time());
}

function get_submissions(): array {
    return read_json('submissions.json', []);
}

function save_submissions(array $rows): bool {
    return write_json('submissions.json', array_values($rows));
}

function append_submission(array $row): bool {
    $all = get_submissions();
    $all[] = $row;
    return save_submissions($all);
}

function latest_dj_message(): ?array {
    $messages = read_json('dj-messages.json', []);
    if (empty($messages)) {
        return null;
    }
    return $messages[array_key_last($messages)];
}

function current_network_message(): array {
    return read_json('network.json', ['global_message' => '', 'type' => '', 'updated_at' => '']);
}

function load_poll(): array {
    return read_json('poll.json', ['question' => '', 'options' => [], 'votes' => []]);
}

function save_poll(array $poll): bool {
    return write_json('poll.json', $poll);
}

function esc(string $value): string {
    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
