/* ========================================
   Quiz Engine & Progress Manager
   ======================================== */

class QuizEngine {
  constructor(questions, options = {}) {
    this.allQuestions = questions;
    this.options = {
      shuffle: options.shuffle !== false,
      timeLimit: options.timeLimit || null,
      mode: options.mode || 'quiz',
      questionCount: options.questionCount || questions.length,
      ...options
    };

    let pool = [...questions];
    if (this.options.shuffle) pool = this.shuffle(pool);
    this.questions = pool.slice(0, Math.min(this.options.questionCount, pool.length));
    this.currentIndex = 0;
    this.answers = {};
    this.startTime = null;
    this.endTime = null;
    this.submitted = {};
  }

  start() {
    this.startTime = Date.now();
    return this;
  }

  getTimeRemaining() {
    if (!this.options.timeLimit || !this.startTime) return null;
    const elapsed = (Date.now() - this.startTime) / 1000 / 60;
    return Math.max(0, this.options.timeLimit - elapsed);
  }

  isTimeUp() {
    const r = this.getTimeRemaining();
    return r !== null && r <= 0;
  }

  getCurrentQuestion() {
    return this.questions[this.currentIndex] || null;
  }

  getQuestion(index) {
    return this.questions[index] || null;
  }

  selectOption(questionId, optionId) {
    if (!this.answers[questionId]) this.answers[questionId] = [];
    const q = this.questions.find(q => q.id === questionId);
    if (!q) return;

    if (q.type === 'multiple') {
      const idx = this.answers[questionId].indexOf(optionId);
      if (idx >= 0) {
        this.answers[questionId].splice(idx, 1);
      } else {
        this.answers[questionId].push(optionId);
      }
    } else {
      this.answers[questionId] = [optionId];
    }
  }

  getSelectedOptions(questionId) {
    return this.answers[questionId] || [];
  }

  isSelected(questionId, optionId) {
    return (this.answers[questionId] || []).includes(optionId);
  }

  submitAnswer(questionId) {
    const q = this.questions.find(q => q.id === questionId);
    if (!q) return null;
    const selected = this.answers[questionId] || [];
    const correct = this.checkAnswer(q, selected);
    this.submitted[questionId] = { selected, correct, timestamp: Date.now() };
    return correct;
  }

  isSubmitted(questionId) {
    return !!this.submitted[questionId];
  }

  checkAnswer(question, selected) {
    if (!selected || selected.length === 0) return false;
    if (selected.length !== question.correct.length) return false;
    const sortedSel = [...selected].sort();
    const sortedCorr = [...question.correct].sort();
    return sortedSel.every((v, i) => v === sortedCorr[i]);
  }

  next() {
    if (this.currentIndex < this.questions.length - 1) {
      this.currentIndex++;
      return true;
    }
    return false;
  }

  previous() {
    if (this.currentIndex > 0) {
      this.currentIndex--;
      return true;
    }
    return false;
  }

  goTo(index) {
    if (index >= 0 && index < this.questions.length) {
      this.currentIndex = index;
      return true;
    }
    return false;
  }

  getResults() {
    this.endTime = Date.now();
    const total = this.questions.length;
    const answered = Object.keys(this.submitted).length;
    const correct = Object.values(this.submitted).filter(a => a.correct).length;
    const score = total > 0 ? Math.round((correct / total) * 1000) : 0;
    return {
      total,
      answered,
      correct,
      incorrect: answered - correct,
      unanswered: total - answered,
      score,
      passed: score >= 700,
      duration: this.endTime - this.startTime,
      answers: this.submitted,
      questions: this.questions
    };
  }

  getProgress() {
    return {
      current: this.currentIndex + 1,
      total: this.questions.length,
      answered: Object.keys(this.submitted).length,
      percentage: Math.round((Object.keys(this.submitted).length / this.questions.length) * 100)
    };
  }

  shuffle(array) {
    for (let i = array.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
  }
}

/* --- Progress Manager --- */
const ProgressManager = {
  prefix: 'certportal-progress-',

  getKey(examId) {
    return this.prefix + examId;
  },

  getProgress(examId) {
    const data = localStorage.getItem(this.getKey(examId));
    if (!data) return { answers: {}, bestScore: 0, attempts: 0, lastAttempt: null };
    try { return JSON.parse(data); } catch { return { answers: {}, bestScore: 0, attempts: 0, lastAttempt: null }; }
  },

  saveAnswer(examId, questionId, selected, correct) {
    const progress = this.getProgress(examId);
    progress.answers[questionId] = {
      selected, correct,
      timestamp: new Date().toISOString()
    };
    localStorage.setItem(this.getKey(examId), JSON.stringify(progress));
  },

  saveQuizResult(examId, results) {
    const progress = this.getProgress(examId);
    progress.attempts = (progress.attempts || 0) + 1;
    progress.lastAttempt = new Date().toISOString();
    if (results.score > (progress.bestScore || 0)) {
      progress.bestScore = results.score;
    }
    Object.entries(results.answers).forEach(([qId, answer]) => {
      progress.answers[qId] = {
        selected: answer.selected,
        correct: answer.correct,
        timestamp: new Date().toISOString()
      };
    });
    localStorage.setItem(this.getKey(examId), JSON.stringify(progress));
  },

  getStats(examId, totalQuestions) {
    const progress = this.getProgress(examId);
    const answered = Object.keys(progress.answers).length;
    const correct = Object.values(progress.answers).filter(a => a.correct).length;
    return {
      answered,
      correct,
      incorrect: answered - correct,
      total: totalQuestions,
      percentage: totalQuestions > 0 ? Math.round((answered / totalQuestions) * 100) : 0,
      correctPercentage: answered > 0 ? Math.round((correct / answered) * 100) : 0,
      bestScore: progress.bestScore || 0,
      attempts: progress.attempts || 0,
      lastAttempt: progress.lastAttempt
    };
  },

  resetProgress(examId) {
    localStorage.removeItem(this.getKey(examId));
  },

  resetAll() {
    const keys = [];
    for (let i = 0; i < localStorage.length; i++) {
      const key = localStorage.key(i);
      if (key && key.startsWith(this.prefix)) keys.push(key);
    }
    keys.forEach(k => localStorage.removeItem(k));
  }
};
