"use client";

import React, { useEffect, useState, useCallback } from "react";
import { useParams, useRouter, useSearchParams } from "next/navigation";
import { useTimer } from "@/context/TimerContext";
import { useExam } from "@/context/ExamContext";
import { API_URL, getToken } from "@/lib/auth";
import Header from "@/components/Header";

// Types
interface Question {
  id: number;
  question: string;
  options: Record<string, string>;
}

interface QuestionItemProps {
  question: Question;
  selectedAnswer?: string;
  handleSelect: (questionId: number, option: string) => void;
}

const QuestionItem = React.memo<QuestionItemProps>(
  ({ question, selectedAnswer, handleSelect }) => (
    <div className="border border-[#8abdff]/50 rounded-2xl p-4">
      <h3 className="text-xl font-medium mb-[20px]">
        {question.id}. {question.question}
      </h3>
      <div className="flex flex-col gap-4 items-start">
        {Object.entries(question.options).map(([key, value]) => (
          <button
            key={key}
            className="flex items-center gap-3"
            onClick={() => handleSelect(question.id, key)}
          >
            <span
              className={`flex items-center rounded-full border px-1.5 ${
                selectedAnswer === key
                  ? "text-white bg-[#113768] border-[#113768]"
                  : ""
              }`}
            >
              {key.toUpperCase()}
            </span>
            <span className="option-description">{value}</span>
          </button>
        ))}
      </div>
    </div>
  )
);

QuestionItem.displayName = "QuestionItem";

export default function ExamPage() {
  const router = useRouter();
  const { id } = useParams();
  const time = useSearchParams().get("time");

  const { setInitialTime, stopTimer } = useTimer();
  const {
    currentAttempt,
    setAnswer,
    getAnswer,
    submitExam: submitExamContext,
    setApiResponse,
    isExamStarted,
    isExamCompleted,
    isHydrated,
    isInitialized,
    currentExam,
  } = useExam();

  const [questions, setQuestions] = useState<Question[] | null>(null);
  const [loading, setLoading] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submissionLoading, setSubmissionLoading] = useState(false);

  useEffect(() => {
    console.log(
      "hydrated:",
      isHydrated,
      "initialized:",
      isInitialized,
      "exam:",
      currentExam
    );
  }, [isHydrated, isInitialized, currentExam]);

  // Initial checks
  useEffect(() => {
    if (!isHydrated || !isInitialized || isSubmitting) return;
    if (!isExamStarted()) return router.push("/unit");
    if (isExamCompleted()) return router.push("/exam/results");
  }, [
    isHydrated,
    isInitialized,
    isExamStarted,
    isExamCompleted,
    isSubmitting,
    router,
  ]);

  // Fetch questions
  useEffect(() => {
    const fetchQuestions = async () => {
      try {
        const response = await fetch(`${API_URL}/mock/${id}`);
        const data = await response.json();
        setQuestions(data.questions);
      } catch (error) {
        console.error("Error fetching questions:", error);
      } finally {
        setLoading(false);
      }
    };
    fetchQuestions();
    if (time) setInitialTime(Number(time));
  }, [id, time, setInitialTime]);

  const handleSelect = useCallback(
    (questionId: number, option: string) => {
      setAnswer(questionId.toString(), option);
    },
    [setAnswer]
  );

  const handleSubmit = async () => {
    if (!currentAttempt) return console.error("No exam attempt found");

    stopTimer();
    setSubmissionLoading(true);
    setIsSubmitting(true);

    const answersForAPI = currentAttempt.answers.reduce(
      (acc, { questionId, answer }) => {
        acc[+questionId] = answer;
        return acc;
      },
      {} as Record<number, string>
    );

    try {
      const response = await fetch(`${API_URL}/submit`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${await getToken()}`,
        },
        body: JSON.stringify({ mock_id: id, data: answersForAPI }),
      });

      if (!response.ok)
        throw new Error((await response.json()).message || "Submission failed");

      const responseData = await response.json();
      submitExamContext();
      setApiResponse(responseData);
      router.push("/exam/results");
    } catch (error) {
      console.error("Error submitting answers:", error);
      setIsSubmitting(false);
    } finally {
      setSubmissionLoading(false);
    }
  };

  const showExitDialog = () => {
    if (window.confirm("Are you sure you want to quit the exam?")) {
      stopTimer();
      router.push("/unit");
    }
  };

  useEffect(() => {
    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      e.preventDefault();
      e.returnValue = "";
    };

    const handlePopState = (e: PopStateEvent) => {
      e.preventDefault();
      showExitDialog();
    };

    window.addEventListener("beforeunload", handleBeforeUnload);
    window.addEventListener("popstate", handlePopState);

    return () => {
      window.removeEventListener("beforeunload", handleBeforeUnload);
      window.removeEventListener("popstate", handlePopState);
    };
  }, []);

  if (submissionLoading) {
    return (
      <div className="min-h-screen bg-gray-50 flex items-center justify-center">
        <div className="text-center">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-900 mb-4"></div>
          <p className="text-lg font-medium text-gray-900">Submitting...</p>
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-50">
      <Header
        examDuration={time}
        displayTabTitle={null}
        image={undefined}
        displayUser={undefined}
        displaySubject={undefined}
      />
      <div className="container mx-auto px-4 py-8">
        {loading ? (
          <div className="flex items-center justify-center min-h-64">
            <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-900"></div>
          </div>
        ) : (
          <div className="space-y-6 mb-20">
            {questions?.map((q) => (
              <QuestionItem
                key={q.id}
                question={q}
                selectedAnswer={getAnswer(q.id.toString())}
                handleSelect={handleSelect}
              />
            ))}
          </div>
        )}

        <div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 p-4">
          <div className="container mx-auto">
            <button
              onClick={handleSubmit}
              disabled={submissionLoading}
              className="w-full bg-blue-900 text-white py-4 px-6 rounded-lg font-bold text-lg hover:bg-blue-800 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              Submit
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
