<?php

declare(strict_types=1);

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../config/database.php';

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_name(SESSION_NAME);
    session_start([
        'cookie_httponly' => true,
        'cookie_samesite' => 'Lax',
        'use_strict_mode' => true,
    ]);
}

function app_base_url(): string
{
    static $baseUrl = null;

    if (is_string($baseUrl)) {
        return $baseUrl;
    }

    if (trim(BASE_URL) !== '') {
        $baseUrl = '/' . trim(BASE_URL, '/');
        return $baseUrl === '/' ? '' : $baseUrl;
    }

    $documentRoot = realpath((string) ($_SERVER['DOCUMENT_ROOT'] ?? ''));
    $applicationRoot = realpath(__DIR__ . '/..');

    if ($documentRoot !== false && $applicationRoot !== false) {
        $documentRoot = rtrim(str_replace('\\', '/', $documentRoot), '/');
        $applicationRoot = rtrim(str_replace('\\', '/', $applicationRoot), '/');

        if (stripos($applicationRoot, $documentRoot) === 0) {
            $relativePath = substr($applicationRoot, strlen($documentRoot));
            $baseUrl = '/' . trim((string) $relativePath, '/');
            return $baseUrl === '/' ? '' : $baseUrl;
        }
    }

    $scriptName = str_replace('\\', '/', (string) ($_SERVER['SCRIPT_NAME'] ?? ''));
    foreach (['/admin/', '/student/'] as $section) {
        $position = strpos($scriptName, $section);
        if ($position !== false) {
            $baseUrl = rtrim(substr($scriptName, 0, $position), '/');
            return $baseUrl;
        }
    }

    $baseUrl = rtrim(str_replace('\\', '/', dirname($scriptName)), '/.');
    return $baseUrl;
}

function url(string $path = ''): string
{
    $baseUrl = app_base_url();
    $cleanPath = ltrim($path, '/');

    if ($cleanPath === '') {
        return $baseUrl === '' ? '/' : $baseUrl . '/';
    }

    return ($baseUrl === '' ? '' : $baseUrl) . '/' . $cleanPath;
}

function redirect(string $path): never
{
    header('Location: ' . url($path));
    exit;
}

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

function csrf_token(): string
{
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function verify_csrf(): void
{
    $token = $_POST['csrf_token'] ?? '';
    if (!is_string($token) || !hash_equals($_SESSION['csrf_token'] ?? '', $token)) {
        http_response_code(419);
        exit('انتهت صلاحية الطلب. أعد تحميل الصفحة وحاول مرة أخرى.');
    }
}

function flash(string $type, string $message): void
{
    $_SESSION['flash'] = compact('type', 'message');
}

function pull_flash(): ?array
{
    $flash = $_SESSION['flash'] ?? null;
    unset($_SESSION['flash']);
    return is_array($flash) ? $flash : null;
}

function student_logged_in(): bool
{
    return isset($_SESSION['student_id']);
}

function admin_logged_in(): bool
{
    return isset($_SESSION['admin_id']);
}

function require_student(): void
{
    if (!student_logged_in()) {
        redirect('login.php');
    }
}

function require_admin(): void
{
    if (!admin_logged_in()) {
        redirect('admin/login.php');
    }
}

function normalize_phone(string $phone): string
{
    $phone = trim($phone);
    $phone = str_replace([' ', '-', '(', ')'], '', $phone);
    return $phone;
}

function valid_phone(string $phone): bool
{
    return (bool) preg_match('/^\+?[0-9]{10,15}$/', $phone);
}

function grade_text(string $grade): string
{
    return $grade === 'first_secondary' ? 'الصف الأول الثانوي' : 'الصف الثاني الثانوي';
}

function youtube_video_id(string $value): ?string
{
    $value = trim($value);
    if ($value === '') {
        return null;
    }

    if (preg_match('/^[A-Za-z0-9_-]{11}$/', $value)) {
        return $value;
    }

    $parts = parse_url($value);
    if ($parts === false) {
        return null;
    }

    $host = strtolower((string) ($parts['host'] ?? ''));
    $path = trim((string) ($parts['path'] ?? ''), '/');

    if (str_contains($host, 'youtu.be')) {
        $candidate = explode('/', $path)[0] ?? '';
        return preg_match('/^[A-Za-z0-9_-]{11}$/', $candidate) ? $candidate : null;
    }

    if (str_contains($host, 'youtube.com') || str_contains($host, 'youtube-nocookie.com')) {
        parse_str((string) ($parts['query'] ?? ''), $query);
        if (!empty($query['v']) && preg_match('/^[A-Za-z0-9_-]{11}$/', (string) $query['v'])) {
            return (string) $query['v'];
        }

        $segments = array_values(array_filter(explode('/', $path)));
        foreach (['embed', 'shorts', 'live'] as $marker) {
            $index = array_search($marker, $segments, true);
            if ($index !== false && isset($segments[$index + 1])) {
                $candidate = $segments[$index + 1];
                return preg_match('/^[A-Za-z0-9_-]{11}$/', $candidate) ? $candidate : null;
            }
        }
    }

    return null;
}

function youtube_embed_url(string $youtubeId): string
{
    return 'https://www.youtube-nocookie.com/embed/' . rawurlencode($youtubeId) . '?rel=0&modestbranding=1';
}

function youtube_watch_url(string $youtubeId): string
{
    return 'https://www.youtube.com/watch?v=' . rawurlencode($youtubeId);
}

function youtube_thumbnail_url(string $youtubeId): string
{
    return 'https://i.ytimg.com/vi/' . rawurlencode($youtubeId) . '/hqdefault.jpg';
}

function student_has_video_access(int $studentId, array $student, array $video): bool
{
    if ((int) ($video['is_free'] ?? 0) === 1) {
        return true;
    }

    $videoLimit = (int) ($student['video_limit'] ?? 0);
    if ($videoLimit > 0) {
        $rankStmt = db()->prepare(
            'SELECT COUNT(*)
             FROM videos
             WHERE grade = ? AND is_active = 1
               AND (sort_order < ? OR (sort_order = ? AND id <= ?))'
        );
        $rankStmt->execute([
            (string) $video['grade'],
            (int) $video['sort_order'],
            (int) $video['sort_order'],
            (int) $video['id'],
        ]);
        if ((int) $rankStmt->fetchColumn() <= $videoLimit) {
            return true;
        }
    }

    $stmt = db()->prepare('SELECT 1 FROM student_video_access WHERE student_id = ? AND video_id = ? LIMIT 1');
    $stmt->execute([$studentId, (int) $video['id']]);
    return (bool) $stmt->fetchColumn();
}

function student_has_quiz_access(int $studentId, array $student, array $quiz): bool
{
    if ((int) ($quiz['is_free'] ?? 0) === 1) {
        return true;
    }

    $quizLimit = (int) ($student['quiz_limit'] ?? 0);
    if ($quizLimit > 0) {
        $rankStmt = db()->prepare(
            'SELECT COUNT(*)
             FROM quizzes
             WHERE grade = ? AND is_active = 1
               AND (sort_order < ? OR (sort_order = ? AND id <= ?))'
        );
        $rankStmt->execute([
            (string) $quiz['grade'],
            (int) $quiz['sort_order'],
            (int) $quiz['sort_order'],
            (int) $quiz['id'],
        ]);
        if ((int) $rankStmt->fetchColumn() <= $quizLimit) {
            return true;
        }
    }

    $stmt = db()->prepare('SELECT 1 FROM student_quiz_access WHERE student_id = ? AND quiz_id = ? LIMIT 1');
    $stmt->execute([$studentId, (int) $quiz['id']]);
    return (bool) $stmt->fetchColumn();
}

function option_letter(int $position): string
{
    return ['أ', 'ب', 'ج', 'د'][$position - 1] ?? (string) $position;
}
