<?php
declare(strict_types=1);

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

if (!function_exists('sendSecurityHeaders')) {
    function sendSecurityHeaders(): void
    {
        if (headers_sent() || PHP_SAPI === 'cli') return;
        header('X-Frame-Options: SAMEORIGIN');
        header('X-Content-Type-Options: nosniff');
        header('Referrer-Policy: strict-origin-when-cross-origin');
        header('Permissions-Policy: camera=(), microphone=(self), geolocation=()');
        header("Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; media-src 'self' https:; frame-src 'self' https://www.youtube.com https://youtube.com https://zoom.us https://*.zoom.us; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; script-src 'self' 'unsafe-inline'; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'self'");
        if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https')) {
            header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
        }
    }
}

if (!function_exists('requireCsrf')) {
    function requireCsrf(): void
    {
        if (isPost() && !verifyCsrf()) {
            http_response_code(419);
            exit('Invalid request token. Please refresh the page and try again.');
        }
    }
}

if (!function_exists('cleanInput')) {
    function cleanInput(?string $value): string { return clean($value); }
}
if (!function_exists('validEmail')) {
    function validEmail(string $email): bool { return filter_var($email, FILTER_VALIDATE_EMAIL) !== false; }
}
if (!function_exists('hashPassword')) {
    function hashPassword(string $password): string { return password_hash($password, PASSWORD_DEFAULT); }
}
if (!function_exists('verifyPassword')) {
    function verifyPassword(string $password, string $hash): bool { return password_verify($password, $hash); }
}
if (!function_exists('strongPassword')) {
    function strongPassword(string $password): bool
    {
        return strlen($password) >= 8
            && preg_match('/[A-Z]/', $password) === 1
            && preg_match('/[a-z]/', $password) === 1
            && preg_match('/\d/', $password) === 1;
    }
}
if (!function_exists('randomCode')) {
    function randomCode(string $prefix = 'SMI', int $digits = 5): string
    {
        $min = 10 ** max(0, $digits - 1);
        $max = (10 ** $digits) - 1;
        return $prefix . '-' . random_int($min, $max);
    }
}
if (!function_exists('tooManyLoginAttempts')) {
    function tooManyLoginAttempts(string $key, int $maxAttempts = 5, int $lockMinutes = 15): bool
    {
        $record = $_SESSION['login_attempts'][$key] ?? null;
        if (!is_array($record)) return false;
        if ((int)($record['locked_until'] ?? 0) > time()) return true;
        if ((int)($record['attempts'] ?? 0) < $maxAttempts) return false;
        $_SESSION['login_attempts'][$key]['locked_until'] = time() + ($lockMinutes * 60);
        return true;
    }
}
if (!function_exists('addLoginAttempt')) {
    function addLoginAttempt(string $key): void
    {
        $record = $_SESSION['login_attempts'][$key] ?? ['attempts' => 0, 'first_at' => time()];
        $record['attempts'] = (int)$record['attempts'] + 1;
        $record['last_at'] = time();
        $_SESSION['login_attempts'][$key] = $record;
    }
}
if (!function_exists('clearLoginAttempts')) {
    function clearLoginAttempts(string $key): void { unset($_SESSION['login_attempts'][$key]); }
}
if (!function_exists('validUpload')) {
    function validUpload(array $file, array $allowedExtensions = [], int $maxSize = MAX_UPLOAD_SIZE): bool
    {
        if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) return false;
        if (!is_uploaded_file((string)($file['tmp_name'] ?? ''))) return false;
        if ((int)($file['size'] ?? 0) <= 0 || (int)$file['size'] > $maxSize) return false;
        $ext = strtolower(pathinfo((string)($file['name'] ?? ''), PATHINFO_EXTENSION));
        return $ext !== '' && ($allowedExtensions === [] || in_array($ext, $allowedExtensions, true));
    }
}
if (!function_exists('secureUpload')) {
    function secureUpload(array $file, string $folder, array $allowedExtensions = []): ?string
    {
        if ($allowedExtensions !== []) {
            $original = defined('ALLOWED_FILE_TYPES') ? ALLOWED_FILE_TYPES : [];
            if (!in_array(strtolower(pathinfo((string)($file['name'] ?? ''), PATHINFO_EXTENSION)), $allowedExtensions, true)) return null;
        }
        return uploadFile($file, $folder);
    }
}
if (!function_exists('preventDirectAccess')) {
    function preventDirectAccess(): void
    {
        if (realpath((string)($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) {
            http_response_code(403);
            exit('Access denied.');
        }
    }
}

sendSecurityHeaders();
