<?php

namespace App\Controllers;

class ApiController {
    private $pdo;
    private $config;
    
    public function __construct($pdo, $config) {
        $this->pdo = $pdo;
        $this->config = $config;
    }
    
    private function jsonResponse($data, $code = 200) {
        http_response_code($code);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }

    private function requireJsonCsrf() {
        $headers = function_exists('getallheaders') ? getallheaders() : [];
        $token = $headers['X-CSRF-Token'] ?? $headers['x-csrf-token'] ?? '';
        if (!$token && isset($_POST['csrf_token'])) $token = $_POST['csrf_token'];
        if (!verify_csrf($token)) { $this->jsonResponse(['error' => 'Invalid CSRF token'], 419); }
    }

    private function loadAttemptQuestions($attemptId) {
        $stmt = $this->pdo->prepare("SELECT q.id, q.question_type, q.question_text, q.points, taq.options_order_json FROM test_attempt_questions taq JOIN questions q ON taq.question_id = q.id WHERE taq.attempt_id = ? ORDER BY taq.sort_order");
        $stmt->execute([$attemptId]);
        $questions = $stmt->fetchAll();
        foreach ($questions as &$question) {
            $optionIds = json_decode($question['options_order_json'] ?? '[]', true) ?: [];
            if ($optionIds) {
                $placeholders = implode(',', array_fill(0, count($optionIds), '?'));
                $opt = $this->pdo->prepare("SELECT id, option_text, sort_order FROM question_options WHERE id IN ($placeholders) ORDER BY FIELD(id, $placeholders)");
                $opt->execute(array_merge($optionIds, $optionIds));
            } else {
                $opt = $this->pdo->prepare("SELECT id, option_text, sort_order FROM question_options WHERE question_id = ? ORDER BY sort_order");
                $opt->execute([$question['id']]);
            }
            $question['options'] = $opt->fetchAll();
            unset($question['options_order_json']);
        }
        return $questions;
    }

    public function testQuestions($attemptId) {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        $user = current_user();
        $stmt = $this->pdo->prepare("SELECT ta.id FROM test_attempts ta WHERE ta.id = ? AND ta.student_id = (SELECT id FROM students WHERE user_id = ? LIMIT 1) AND ta.status = 'in_progress'");
        $stmt->execute([$attemptId, $user['id']]);
        if (!$stmt->fetchColumn()) { $this->jsonResponse(['error' => 'Invalid attempt'], 404); }
        $this->jsonResponse(['success' => true, 'questions' => $this->loadAttemptQuestions($attemptId)]);
    }
    
    public function getModules($courseId) {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        $stmt = $this->pdo->prepare("SELECT id, title, slug, sort_order FROM modules WHERE course_id = ? AND is_published = 1 ORDER BY sort_order");
        $stmt->execute([$courseId]);
        $this->jsonResponse($stmt->fetchAll());
    }
    
    public function getLessons($moduleId) {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        $stmt = $this->pdo->prepare("SELECT id, title, slug, lesson_type, sort_order FROM lessons WHERE module_id = ? AND is_published = 1 ORDER BY sort_order");
        $stmt->execute([$moduleId]);
        $this->jsonResponse($stmt->fetchAll());
    }
    
    public function markLessonComplete($lessonId) {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        $user = current_user();
        if ($user['role_slug'] !== 'student') { $this->jsonResponse(['error' => 'Forbidden'], 403); }
        
        $stmt = $this->pdo->prepare("SELECT s.id FROM students s WHERE s.user_id = ?");
        $stmt->execute([$user['id']]);
        $studentId = $stmt->fetchColumn();
        
        if (!$studentId) { $this->jsonResponse(['error' => 'Student not found'], 404); }
        
        $this->pdo->prepare("INSERT IGNORE INTO activity_logs (user_id, student_id, activity_type, description, metadata) VALUES (?, ?, 'lesson_complete', ?, ?)")->execute([$user['id'], $studentId, 'Completed lesson', json_encode(['lesson_id' => $lessonId])]);
        
        $this->jsonResponse(['success' => true, 'message' => 'Lesson marked as complete']);
    }
    
    public function submitTest() {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->jsonResponse(['error' => 'Method not allowed'], 405); }
        $this->requireJsonCsrf();
        
        $data = json_decode(file_get_contents('php://input'), true);
        if (!$data) { $this->jsonResponse(['error' => 'Invalid data'], 400); }
        
        $attemptId = $data['attempt_id'] ?? 0;
        $answers = $data['answers'] ?? [];
        
        $user = current_user();
        $stmt = $this->pdo->prepare("SELECT ta.*, t.pass_mark, t.negative_marking, t.negative_mark_value FROM test_attempts ta JOIN tests t ON ta.test_id = t.id WHERE ta.id = ? AND ta.student_id = (SELECT id FROM students WHERE user_id = ? LIMIT 1) AND ta.status = 'in_progress'");
        $stmt->execute([$attemptId, $user['id']]);
        $attempt = $stmt->fetch();
        
        if (!$attempt) { $this->jsonResponse(['error' => 'Invalid or completed attempt'], 400); }
        
        $totalPoints = 0;
        $earnedPoints = 0;
        
        foreach ($answers as $answer) {
            $questionId = $answer['question_id'] ?? 0;
            $selectedOptionId = $answer['selected_option_id'] ?? null;
            $answerText = $answer['answer_text'] ?? null;
            
            $stmt = $this->pdo->prepare("SELECT q.* FROM test_attempt_questions taq JOIN questions q ON taq.question_id = q.id WHERE taq.attempt_id = ? AND q.id = ?");
            $stmt->execute([$attemptId, $questionId]);
            $question = $stmt->fetch();
            if (!$question) continue;
            
            $totalPoints += $question['points'];
            $isCorrect = 0;
            $pointsAwarded = 0;
            
            if ($question['question_type'] === 'multiple_choice' || $question['question_type'] === 'true_false') {
                $stmt = $this->pdo->prepare("SELECT is_correct FROM question_options WHERE id = ? AND question_id = ?");
                $stmt->execute([$selectedOptionId, $questionId]);
                if ($stmt->fetchColumn() == 1) {
                    $isCorrect = 1;
                    $pointsAwarded = $question['points'];
                } elseif ($attempt['negative_marking']) {
                    $pointsAwarded = -$question['points'] * $attempt['negative_mark_value'];
                }
            }
            
            $this->pdo->prepare("INSERT INTO test_attempt_answers (attempt_id, question_id, selected_option_id, answer_text, is_correct, points_awarded) VALUES (?, ?, ?, ?, ?, ?)")->execute([$attemptId, $questionId, $selectedOptionId, $answerText, $isCorrect, $pointsAwarded]);
            $earnedPoints += $pointsAwarded;
        }
        
        $maxScore = $totalPoints;
        $score = max(0, $earnedPoints);
        $percentage = $maxScore > 0 ? round(($score / $maxScore) * 100, 2) : 0;
        $passed = $percentage >= $attempt['pass_mark'] ? 1 : 0;
        
        $this->pdo->prepare("UPDATE test_attempts SET score = ?, max_score = ?, pass_mark = ?, passed = ?, status = 'completed', ended_at = NOW(), time_spent = TIMESTAMPDIFF(SECOND, started_at, NOW()) WHERE id = ?")->execute([$score, $maxScore, $attempt['pass_mark'], $passed, $attemptId]);
        
        log_audit($user['id'], 'test_submit', 'test_attempt', $attemptId);
        
        $this->jsonResponse(['success' => true, 'score' => $score, 'max_score' => $maxScore, 'percentage' => $percentage, 'passed' => $passed, 'pass_mark' => $attempt['pass_mark']]);
    }
    
    public function saveTestProgress() {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->jsonResponse(['error' => 'Method not allowed'], 405); }
        $this->requireJsonCsrf();
        
        $data = json_decode(file_get_contents('php://input'), true);
        $attemptId = $data['attempt_id'] ?? 0;
        $answers = $data['answers'] ?? [];
        $tabSwitches = $data['tab_switches'] ?? 0;
        
        $user = current_user();
        $stmt = $this->pdo->prepare("SELECT ta.* FROM test_attempts ta WHERE ta.id = ? AND ta.student_id = (SELECT id FROM students WHERE user_id = ? LIMIT 1) AND ta.status = 'in_progress'");
        $stmt->execute([$attemptId, $user['id']]);
        if (!$stmt->fetch()) { $this->jsonResponse(['error' => 'Invalid attempt'], 400); }
        
        $this->pdo->prepare("UPDATE test_attempts SET tab_switches = ? WHERE id = ?")->execute([$tabSwitches, $attemptId]);
        
        $this->jsonResponse(['success' => true]);
    }
    
    public function saveProgress() {
        return $this->saveTestProgress();
    }
    
    public function tabSwitch($attemptId) {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->jsonResponse(['error' => 'Method not allowed'], 405); }
        $this->requireJsonCsrf();
        
        $user = current_user();
        $this->pdo->prepare("UPDATE test_attempts SET tab_switches = tab_switches + 1, suspicious_flags = CONCAT(COALESCE(suspicious_flags, ''), 'TAB_SWITCH:', NOW(), ';') WHERE id = ? AND student_id = (SELECT id FROM students WHERE user_id = ? LIMIT 1)")->execute([$attemptId, $user['id']]);
        
        $this->jsonResponse(['success' => true]);
    }
    
    public function enrollments() {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        $user = current_user();
        if (!in_array($user['role_slug'], ['super_admin', 'academic_admin'])) { $this->jsonResponse(['error' => 'Forbidden'], 403); }
        
        $courseId = $_GET['course_id'] ?? 0;
        if ($courseId) {
            $stmt = $this->pdo->prepare("SELECT s.student_number, u.first_name, u.last_name, e.enrolled_at, e.status FROM enrollments e JOIN students s ON e.student_id = s.id JOIN users u ON s.user_id = u.id WHERE e.course_id = ?");
            $stmt->execute([$courseId]);
        } else {
            $stmt = $this->pdo->query("SELECT s.student_number, u.first_name, u.last_name, e.enrolled_at, e.status, c.title as course_title FROM enrollments e JOIN students s ON e.student_id = s.id JOIN users u ON s.user_id = u.id JOIN courses c ON e.course_id = c.id ORDER BY e.enrolled_at DESC LIMIT 50");
        }
        $this->jsonResponse($stmt->fetchAll());
    }
    
    public function dashboardStats() {
        if (!is_logged_in()) { $this->jsonResponse(['error' => 'Unauthorized'], 401); }
        $user = current_user();
        if ($user['role_slug'] !== 'student') { $this->jsonResponse(['error' => 'Forbidden'], 403); }
        
        $stmt = $this->pdo->prepare("SELECT id FROM students WHERE user_id = ?");
        $stmt->execute([$user['id']]);
        $studentId = $stmt->fetchColumn();
        
        if (!$studentId) { $this->jsonResponse(['error' => 'Not found'], 404); }
        
        $stats = [];
        $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM enrollments WHERE student_id = ? AND status = 'active'");
        $stmt->execute([$studentId]);
        $stats['active_courses'] = $stmt->fetchColumn();
        
        $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM test_attempts WHERE student_id = ? AND status = 'completed'");
        $stmt->execute([$studentId]);
        $stats['tests_taken'] = $stmt->fetchColumn();
        
        $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM certificates WHERE student_id = ? AND status = 'issued'");
        $stmt->execute([$studentId]);
        $stats['certificates'] = $stmt->fetchColumn();
        
        $this->jsonResponse($stats);
    }
    
    public function manifest() {
        $pwa = $this->pdo->query("SELECT * FROM pwa_settings WHERE is_enabled = 1 LIMIT 1")->fetch();
        if (!$pwa) { $pwa = ['app_name' => 'CIX Orbit Academy', 'short_name' => 'CIX Academy', 'description' => 'Learn. Build. Automate. Grow.', 'theme_color' => '#000000', 'background_color' => '#ffffff', 'display_mode' => 'standalone', 'orientation' => 'portrait', 'start_url' => '/']; }
        
        header('Content-Type: application/json');
        echo json_encode([
            'name' => $pwa['app_name'],
            'short_name' => $pwa['short_name'],
            'description' => $pwa['description'],
            'start_url' => $pwa['start_url'],
            'display' => $pwa['display_mode'],
            'orientation' => $pwa['orientation'],
            'background_color' => $pwa['background_color'],
            'theme_color' => $pwa['theme_color'],
            'icons' => [
                ['src' => '/public/assets/images/icon-192.png', 'sizes' => '192x192', 'type' => 'image/png', 'purpose' => 'any'],
                ['src' => '/public/assets/images/icon-512.png', 'sizes' => '512x512', 'type' => 'image/png', 'purpose' => 'any'],
                ['src' => '/public/assets/images/maskable-icon.png', 'sizes' => '512x512', 'type' => 'image/png', 'purpose' => 'maskable']
            ]
        ], JSON_PRETTY_PRINT);
        exit;
    }
    
    public function serviceWorker() {
        header('Content-Type: application/javascript');
        echo 'const CACHE_NAME="cix-academy-v1";const ASSETS=["/","/assets/css/style.css","/assets/js/app.js","https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css","https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css","https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"];self.addEventListener("install",e=>{e.waitUntil(caches.open(CACHE_NAME).then(c=>c.addAll(ASSETS)))});self.addEventListener("fetch",e=>{if(e.request.url.includes("/api/")||e.request.url.includes("test")){return}e.respondWith(caches.match(e.request).then(r=>r||fetch(e.request).then(r=>{if(r.status===200){const clone=r.clone();caches.open(CACHE_NAME).then(c=>c.put(e.request,clone))}return r}).catch(()=>caches.match("/"))))});self.addEventListener("activate",e=>{e.waitUntil(caches.keys().then(keys=>Promise.all(keys.filter(k=>k!==CACHE_NAME).map(k=>caches.delete(k)))))});';
        exit;
    }
}
