"use client";

import React, { createContext, useContext, useState } from "react";
import { Test, Answer } from "@/types/exam";
import { API_URL } from "@/lib/auth";
import { getToken } from "@/lib/auth";

interface ExamContextType {
  test: Test | null;
  answers: Answer[];
  startExam: (testType: string, testId: string) => Promise<void>;
  setAnswer: (questionIndex: number, answer: Answer) => void;
  submitExam: () => Promise<void>;
  cancelExam: () => void;
}

const ExamContext = createContext<ExamContextType | undefined>(undefined);

export const ExamProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const [test, setTest] = useState<Test | null>(null);
  const [answers, setAnswers] = useState<Answer[]>([]);

  // start exam
  const startExam = async (testType: string, testId: string) => {
    try {
      const token = await getToken(); // if needed
      const res = await fetch(`${API_URL}/tests/${testType}/${testId}`, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      if (!res.ok) throw new Error(`Failed to fetch test: ${res.status}`);
      const data: Test = await res.json();
      setTest(data);
      setAnswers(Array(data.questions.length).fill(null));
    } catch (err) {
      console.error("startExam error:", err);
    }
  };

  // update answer
  const setAnswer = (questionIndex: number, answer: Answer) => {
    setAnswers((prev) => {
      const updated = [...prev];
      updated[questionIndex] = answer;
      return updated;
    });
  };

  // submit exam
  const submitExam = async () => {
    if (!test) return;
    const token = await getToken();
    try {
      const { type, test_id, attempt_id } = test.metadata;
      const res = await fetch(
        `${API_URL}/tests/${type}/${test_id}/${attempt_id}`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            authorization: `Bearer ${token}`,
          },
          body: JSON.stringify({ answers }),
        }
      );
      if (!res.ok) throw new Error("Failed to submit exam");

      // clear
      setTest(null);
      setAnswers([]);
    } catch (err) {
      console.error("Failed to submit exam. Reason:", err);
    }
  };

  // cancel exam
  const cancelExam = () => {
    setTest(null);
    setAnswers([]);
  };

  return (
    <ExamContext.Provider
      value={{ test, answers, startExam, setAnswer, submitExam, cancelExam }}
    >
      {children}
    </ExamContext.Provider>
  );
};

export const useExam = (): ExamContextType => {
  const ctx = useContext(ExamContext);
  if (!ctx) throw new Error("useExam must be used inside ExamProvider");
  return ctx;
};
