export type QuestionStatus = 'not_started' | 'in_progress' | 'completed' | 'skipped';

export interface QuizQuestion {
  id: number;
  question: string | { th: string; en: string };
  is_skippable: boolean;
  type: string;
  choices?: { id: number; text: string | { th: string; en: string } }[];
}

export interface AnswerState {
  questionId: number;
  value: any;
  is_saved: boolean;
  status: QuestionStatus;
  touched: boolean;
  last_saved_at?: string;
}

/**
 * @composable useQuizRunner
 * @description Manages the state and logic for running a quiz activity.
 */
export const useQuizRunner = () => {
  // State
  const questions = useState<QuizQuestion[]>('quiz-questions', () => []);
  const answers = useState<Record<number, AnswerState>>('quiz-answers', () => ({}));
  const currentQuestionIndex = useState<number>('quiz-current-index', () => 0);
  const loading = useState<boolean>('quiz-loading', () => false);
  const lastError = useState<string | null>('quiz-error', () => null);

  // Getters
  const currentQuestion = computed(() => questions.value[currentQuestionIndex.value]);
  
  const currentAnswer = computed(() => {
    if (!currentQuestion.value) return null;
    return answers.value[currentQuestion.value.id];
  });

  const totalQuestions = computed(() => questions.value.length);
  const isLastQuestion = computed(() => currentQuestionIndex.value === questions.value.length - 1);
  const isFirstQuestion = computed(() => currentQuestionIndex.value === 0);

  // Actions
  function initQuiz(quizData: any) {
    if (!quizData || !quizData.questions) return;
    
    questions.value = quizData.questions; 
    currentQuestionIndex.value = 0;
    answers.value = {};
    lastError.value = null;

    questions.value.forEach(q => {
      answers.value[q.id] = {
        questionId: q.id,
        value: null,
        is_saved: false,
        status: 'not_started',
        touched: false,
      };
    });

    if (questions.value.length > 0) {
      enterQuestion(questions.value[0].id);
    }
  }

  function enterQuestion(qId: number) {
    const ans = answers.value[qId];
    if (ans) {
      ans.touched = true;
      if (ans.status === 'not_started' || ans.status === 'skipped') {
         ans.status = 'in_progress';
      }
    }
  }

  function canLeaveCurrent(): { allowed: boolean; reason?: string } {
    if (!currentQuestion.value) return { allowed: true };
    const q = currentQuestion.value;
    const a = answers.value[q.id];
    
    if (a.status === 'completed' || a.is_saved) return { allowed: true };
    if (q.is_skippable) return { allowed: true };
    
    if (!a.is_saved && a.value === null) {
      return { allowed: false, reason: 'This question is required.' };
    }

    return { allowed: true };
  }

  function updateAnswer(val: any) {
     if (!currentQuestion.value) return;
     const qId = currentQuestion.value.id;
     answers.value[qId].value = val;
     
     if (answers.value[qId].is_saved) {
        answers.value[qId].is_saved = false;
        answers.value[qId].status = 'in_progress';
     }
  }

  async function saveCurrentAnswer() {
    if (!currentQuestion.value) return;
    const qId = currentQuestion.value.id;
    const ans = answers.value[qId];

    if (ans.value === null) {
      lastError.value = "Please provide an answer.";
      return false;
    }

    loading.value = true;
    lastError.value = null;

    try {
      ans.is_saved = true;
      ans.status = 'completed';
      ans.last_saved_at = new Date().toISOString();
      return true;
    } catch (e) {
      lastError.value = "Failed to save answer.";
      return false;
    } finally {
      loading.value = false;
    }
  }

  function handleLeaveLogic(targetIndex: number) {
    if (targetIndex === currentQuestionIndex.value) return;

    const check = canLeaveCurrent();
    if (!check.allowed) {
      lastError.value = check.reason || "Required question.";
      return false;
    }

    const currQ = currentQuestion.value;
    if (currQ) {
        const currAns = answers.value[currQ.id];
        if (currAns.status !== 'completed' && !currAns.is_saved) {
          currAns.status = 'skipped';
        }
    }

    currentQuestionIndex.value = targetIndex;
    lastError.value = null;

    if (questions.value[targetIndex]) {
       enterQuestion(questions.value[targetIndex].id);
    }
    
    return true;
  }

  return {
    questions,
    answers,
    currentQuestionIndex,
    loading,
    lastError,
    currentQuestion,
    currentAnswer,
    totalQuestions,
    isFirstQuestion,
    isLastQuestion,
    initQuiz,
    updateAnswer,
    saveCurrentAnswer,
    nextQuestion: () => handleLeaveLogic(currentQuestionIndex.value + 1),
    prevQuestion: () => handleLeaveLogic(currentQuestionIndex.value - 1),
    goToQuestion: (index: number) => handleLeaveLogic(index)
  };
};
