<?php
// Set default timezone to Africa Central Time (CAT, UTC+2) for Harare, Zimbabwe
date_default_timezone_set('Africa/Harare');

// Load environment variables
require_once __DIR__ . '/../vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();

require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/rbac.php';
define('BASE_URL', '/lms/');

// Include ExamService
require_once __DIR__ . '/ExamService.php';
function registerUser($username, $email, $password, $role) {
    $pdo = getDB();

    // Check if username or email already exists
    $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? OR email = ? LIMIT 1");
    $stmt->execute([$username, $email]);
    if ($stmt->fetch()) {
        return ['success' => false, 'message' => 'Username or email already exists'];
    }

    // Hash the password
    $passwordHash = password_hash($password, PASSWORD_DEFAULT);

    // Insert new user into database
    $stmt = $pdo->prepare("INSERT INTO users (username, email, password, role, created_at) VALUES (?, ?, ?, ?, NOW())");
    try {
        $stmt->execute([$username, $email, $passwordHash, $role]);
        return ['success' => true, 'message' => 'Registration successful. You can now login.'];
    } catch (PDOException $e) {
        return ['success' => false, 'message' => 'Error during registration: ' . $e->getMessage()];
    }
}

function getSiteSetting($key) {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT setting_value FROM site_settings WHERE setting_key = ? LIMIT 1");
    $stmt->execute([$key]);
    $result = $stmt->fetch();
    return $result ? $result['setting_value'] : null;
}

function updateSiteSetting($key, $value) {
    $pdo = getDB();
    
    // Check if setting exists
    $stmt = $pdo->prepare("SELECT id FROM site_settings WHERE setting_key = ? LIMIT 1");
    $stmt->execute([$key]);
    $existing = $stmt->fetch();
    
    if ($existing) {
        // Update existing setting
        $stmt = $pdo->prepare("UPDATE site_settings SET setting_value = ?, updated_at = NOW() WHERE setting_key = ?");
        return $stmt->execute([$value, $key]);
    } else {
        // Insert new setting
        $stmt = $pdo->prepare("INSERT INTO site_settings (setting_key, setting_value, created_at, updated_at) VALUES (?, ?, NOW(), NOW())");
        return $stmt->execute([$key, $value]);
    }
}

function getAllPublishedPosts($limit = null, $search = null) {
    $pdo = getDB();
    $sql = "SELECT p.*, c.name as category_name, COALESCE(u.username, p.manual_author_name) as author_name FROM posts p LEFT JOIN categories c ON p.category_id = c.id LEFT JOIN users u ON p.author_id = u.id WHERE p.status = 'published'";
    $params = [];

    if ($search) {
        $sql .= " AND (p.title LIKE ? OR p.content LIKE ?)";
        $params[] = "%$search%";
        $params[] = "%$search%";
    }

    $sql .= " ORDER BY p.created_at DESC";

    if ($limit) {
        $sql .= " LIMIT ?";
        $params[] = $limit;
    }

    $stmt = $pdo->prepare($sql);
    $i = 1;
    if ($search) {
        $stmt->bindValue($i++, "%$search%", PDO::PARAM_STR);
        $stmt->bindValue($i++, "%$search%", PDO::PARAM_STR);
    }
    if ($limit) {
        $stmt->bindValue($i++, $limit, PDO::PARAM_INT);
    }
    $stmt->execute();
    return $stmt->fetchAll();
}

function getCategories() {
    $pdo = getDB();
    $stmt = $pdo->query("SELECT * FROM categories ORDER BY name");
    return $stmt->fetchAll();
}

function getUsers() {
    $pdo = getDB();
    $stmt = $pdo->query("SELECT id, username, email FROM users ORDER BY username");
    return $stmt->fetchAll();
}

function getActiveAnnouncements() {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT * FROM announcements WHERE status = 'active' AND show_on_home = 1 ORDER BY created_at DESC");
    $stmt->execute();
    return $stmt->fetchAll();
}

function formatDate($date) {
    return date('M j, Y', strtotime($date));
}

function truncateText($text, $length = 150) {
    if (strlen($text) <= $length) {
        return $text;
    }
    return substr($text, 0, $length) . '...';
}

function createSlug($text) {
    // Convert to lowercase
    $slug = strtolower($text);

    // Replace non-letter or non-digits with hyphens
    $slug = preg_replace('/[^a-z0-9]+/', '-', $slug);

    // Remove leading/trailing hyphens
    $slug = trim($slug, '-');

    // Ensure slug is not empty
    if (empty($slug)) {
        $slug = 'module-' . time();
    }

    return $slug;
}

function generateSlug($text) {
    return createSlug($text);
}

function logUserActivity($user_id, $action_type, $description) {
    $pdo = getDB();
    $stmt = $pdo->prepare("
        INSERT INTO user_activities (user_id, action_type, action_description, ip_address, user_agent)
        VALUES (?, ?, ?, ?, ?)
    ");
    $stmt->execute([
        $user_id,
        $action_type,
        $description,
        $_SERVER['REMOTE_ADDR'] ?? '',
        $_SERVER['HTTP_USER_AGENT'] ?? ''
    ]);
}

function getCategoryBySlug($slug) {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT * FROM categories WHERE slug = ? LIMIT 1");
    $stmt->execute([$slug]);
    return $stmt->fetch();
}

function getPostsByCategory($category_slug) {
    $pdo = getDB();
    $sql = "SELECT p.*, c.name as category_name, COALESCE(u.username, p.manual_author_name) as author_name FROM posts p LEFT JOIN categories c ON p.category_id = c.id LEFT JOIN users u ON p.author_id = u.id WHERE p.status = 'published' AND c.slug = ? ORDER BY p.created_at DESC";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$category_slug]);
    return $stmt->fetchAll();
}

function getPostBySlug($slug) {
    $pdo = getDB();
    $sql = "SELECT p.*, c.name as category_name, COALESCE(u.username, p.manual_author_name) as author_name FROM posts p LEFT JOIN categories c ON p.category_id = c.id LEFT JOIN users u ON p.author_id = u.id WHERE p.status = 'published' AND p.slug = ? LIMIT 1";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$slug]);
    return $stmt->fetch();
}

function getPostById($id) {
    $pdo = getDB();
    $sql = "SELECT p.*, c.name as category_name, COALESCE(u.username, p.manual_author_name) as author_name FROM posts p LEFT JOIN categories c ON p.category_id = c.id LEFT JOIN users u ON p.author_id = u.id WHERE p.status = 'published' AND p.id = ? LIMIT 1";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$id]);
    return $stmt->fetch();
}

function renderStudentDashboardLink($base_url) {
    if (isLoggedIn() && hasRole('student')) {
        echo '<a href="' . htmlspecialchars($base_url) . 'student/dashboard.php" class="nav-link">Student Dashboard</a>';
    }
}

function isMobile() {
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
    return preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i', $userAgent);
}

function sanitizeContent($content) {
    // Define allowed HTML tags
    $allowedTags = '<p><br><strong><b><em><i><u><ul><ol><li><h1><h2><h3><h4><h5><h6><blockquote><a><img><table><thead><tbody><tr><th><td><span><div><hr><pre><code>';

    // Strip dangerous tags and attributes
    $content = strip_tags($content, $allowedTags);

    // Remove potentially dangerous attributes like onclick, onload, etc.
    $content = preg_replace('/\s+(on\w+|style|javascript:|vbscript:|data:\w+)\s*=\s*["\']*["\']/i', '', $content);

    // Remove script and style tags completely (in case strip_tags missed them)
    $content = preg_replace('/<script[^>]*>.*?<\/script>/is', '', $content);
    $content = preg_replace('/<style[^>]*>.*?<\/style>/is', '', $content);

    return $content;
}

function fetchNewsFromAPI($page = 1, $pageSize = 10) {
    $config = require __DIR__ . '/../config/lms.php';
    $newsConfig = $config['lms']['third_party_integrations']['news_api'];

    if (!$newsConfig['enabled'] || empty($newsConfig['api_key'])) {
        return [];
    }

    $apiKey = $newsConfig['api_key'];
    $country = $newsConfig['default_country'];
    $url = $newsConfig['base_url'] . 'top-headlines?country=' . $country . '&pageSize=' . $pageSize . '&page=' . $page . '&apiKey=' . $apiKey;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // For development, remove in production
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        return [];
    }

    $data = json_decode($response, true);
    if (!$data || $data['status'] !== 'ok') {
        return [];
    }

    return $data['articles'] ?? [];
}

// ===========================================================
// EXAM HELPER FUNCTIONS
// ===========================================================

/**
 * Get exam service instance
 */
function getExamService() {
    return new ExamService();
}

/**
 * Start an exam attempt
 */
function startExamAttempt($examId, $studentId) {
    $service = getExamService();
    return $service->startAttempt($examId, $studentId);
}

/**
 * Save exam progress
 */
function saveExamProgress($attemptId, $answers, $timeSpent = 0) {
    $service = getExamService();
    return $service->saveProgress($attemptId, $answers, $timeSpent);
}

/**
 * Submit exam
 */
function submitExam($attemptId, $answers, $timeSpent = 0) {
    $service = getExamService();
    return $service->submitExam($attemptId, $answers, $timeSpent);
}

/**
 * Get active exam attempt
 */
function getActiveExamAttempt($examId, $studentId) {
    $service = getExamService();
    return $service->getActiveAttempt($examId, $studentId);
}

/**
 * Get exam attempt by ID
 */
function getExamAttempt($attemptId) {
    $service = getExamService();
    return $service->getAttemptById($attemptId);
}

/**
 * Get attempts by student
 */
function getStudentExamAttempts($studentId, $examId = null) {
    $service = getExamService();
    return $service->getAttemptsByStudent($studentId, $examId);
}

/**
 * Get attempts by exam
 */
function getExamAttempts($examId, $status = null) {
    $service = getExamService();
    return $service->getAttemptsByExam($examId, $status);
}

/**
 * Get complete exam submission
 */
function getExamSubmission($attemptId) {
    $service = getExamService();
    return $service->getCompleteSubmission($attemptId);
}

/**
 * Get student answers for an attempt
 */
function getAttemptAnswers($attemptId) {
    $service = getExamService();
    return $service->getAnswersByAttempt($attemptId);
}

/**
 * Grade individual answer
 */
function gradeStudentAnswer($answerId, $score, $feedback, $gradedBy) {
    $service = getExamService();
    return $service->gradeAnswer($answerId, $score, $feedback, $gradedBy);
}

/**
 * Bulk grade attempt
 */
function bulkGradeAttempt($attemptId, $questionScores, $gradedBy) {
    $service = getExamService();
    return $service->bulkGradeAttempt($attemptId, $questionScores, $gradedBy);
}

/**
 * Get ungraded answers for an exam
 */
function getUngradedExamAnswers($examId) {
    $service = getExamService();
    return $service->getUngradedAnswers($examId);
}

/**
 * Get pending grading count
 */
function getPendingGradingCount($examId = null, $instructorId = null) {
    $service = getExamService();
    return $service->getPendingGradingCount($examId, $instructorId);
}

/**
 * Abandon exam attempt
 */
function abandonExamAttempt($attemptId, $reason = 'manual') {
    $service = getExamService();
    return $service->abandonAttempt($attemptId, $reason);
}

/**
 * Check if attempt time has expired
 */
function isExamTimeExpired($attempt) {
    $service = getExamService();
    return $service->isTimeExpired($attempt);
}

/**
 * Get remaining time for attempt
 */
function getExamTimeRemaining($attempt) {
    $service = getExamService();
    return $service->getTimeRemaining($attempt);
}

/**
 * Save student answer during exam
 */
function saveStudentAnswer($examId, $studentId, $attemptId, $questionId, $answerContent, $status = 'in_progress') {
    $service = getExamService();
    return $service->saveOrUpdateStudentAnswer($examId, $studentId, $attemptId, $questionId, $answerContent, $status);
}

/**
 * Get answers by question
 */
function getQuestionAnswers($questionId, $examId = null) {
    $service = getExamService();
    return $service->getAnswersByQuestion($questionId, $examId);
}
?>
