import React, { useCallback, useEffect, useState, useRef } from "react";
import { useRouter } from "next/router";
import { useAuth } from "../../../../contexts/auth";
import { useSkillApi } from "../../../../utils/hooks/useSkillApi";
import PsychometricHeader from "../../../../components/header/PsychometricHeader";
import PsychometricSidebar from "../../../../components/header/PsychometricSidebar";
import BreadCrumb from "../../../../components/dashboard/common/BreadCrumb";
import Seo from "../../../../components/common/Seo";
import PsychometricQuestion from "../../../../components/dashboard/candidate-dashboard/psychometric-test/PsychometricQuestion";
import CopyrightFooter from "../../../../components/dashboard/common/CopyrightFooter";
import Swal from "sweetalert2";

interface Answer {
  questionId: number;
  optionId: number | string;
}

interface Topic {
  id: number;
  name: string;
}

const sanitizeAnswersByQuestions = (
  rawAnswers: Answer[],
  questions: any[],
): Answer[] => {
  if (!Array.isArray(rawAnswers) || !Array.isArray(questions)) return [];

  const validQuestionIds = new Set(
    questions
      .map((q) => Number(q?.id))
      .filter((id) => Number.isFinite(id) && id > 0),
  );

  const latestByQuestionId = new Map<number, number | string>();

  rawAnswers.forEach((answer) => {
    const questionId = Number(answer?.questionId);
    const optionId = answer?.optionId;
    const hasValidOptionId =
      (typeof optionId === "number" &&
        Number.isFinite(optionId) &&
        optionId > 0) ||
      (typeof optionId === "string" && optionId.trim().length > 0);
    if (
      Number.isFinite(questionId) &&
      questionId > 0 &&
      validQuestionIds.has(questionId) &&
      hasValidOptionId
    ) {
      latestByQuestionId.set(questionId, optionId);
    }
  });

  return Array.from(latestByQuestionId.entries()).map(
    ([questionId, optionId]) => ({
      questionId,
      optionId,
    }),
  );
};

const SkillTakePage: React.FC = () => {
  const router = useRouter();
  const { id } = router.query;
  const testId = Number(id || 0);
  const {
    getTest,
    getExams,
    startTest,
    submitTest,
    getResults,
    saveExamAnswers,
    loadExamAnswers,
    clearExamAnswers,
  } = useSkillApi() as any;
  const {
    isAuthenticated,
    loading: authLoading,
    userRole,
    user,
  } = useAuth() as any;

  const [questions, setQuestions] = useState<any[]>([]);
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const [answers, setAnswers] = useState<Answer[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [performanceId, setPerformanceId] = useState<number | null>(null);
  const [jobPostId, setJobPostId] = useState<number | null>(null);
  const [examId, setExamId] = useState<number | null>(null);
  const [getIsSidebarOpen, setIsSidebarOpen] = useState(false);
  const [topics, setTopics] = useState<Topic[]>([]);
  const [currentTopicId, setCurrentTopicId] = useState<number | null>(null);
  const [examDuration, setExamDuration] = useState<number | null>(null);

  // Ref to prevent duplicate startTest calls
  const startTestCalledRef = useRef(false);

  // Ref to prevent duplicate timer setup
  const timerStartedRef = useRef(false);

  // Ref to store current answers for auto-submission (avoids stale closures)
  const answersRef = useRef<Answer[]>([]);
  const performanceIdRef = useRef<number | null>(null);
  const jobPostIdRef = useRef<number | null>(null);

  // Refs for functions that may change between renders — prevents timer from
  // being reset when the parent hook recreates these function references
  const submitTestRef = useRef(submitTest);
  const clearExamAnswersRef = useRef(clearExamAnswers);
  const routerRef = useRef(router);
  const hasSubmittedRef = useRef(false);
  const isExitSubmittingRef = useRef(false);

  // Keep function refs in sync without triggering timer re-setup
  useEffect(() => {
    submitTestRef.current = submitTest;
  }, [submitTest]);

  useEffect(() => {
    clearExamAnswersRef.current = clearExamAnswers;
  }, [clearExamAnswers]);

  useEffect(() => {
    routerRef.current = router;
  }, [router]);

  // Update data refs whenever state changes
  useEffect(() => {
    answersRef.current = answers;
  }, [answers]);

  useEffect(() => {
    performanceIdRef.current = performanceId;
  }, [performanceId]);

  useEffect(() => {
    jobPostIdRef.current = jobPostId;
  }, [jobPostId]);

  const buildSubmitPayload = useCallback(() => {
    const currentAnswers = sanitizeAnswersByQuestions(answersRef.current, questions);
    const answersObject: Record<string, string | number> = {};
    currentAnswers.forEach((a) => {
      answersObject[String(a.questionId)] = a.optionId;
    });

    const currentPerformanceId = performanceIdRef.current;
    const currentJobPostId = jobPostIdRef.current;
    const payload: any = {
      performanceId: currentPerformanceId || testId,
      answers: answersObject,
    };

    if (currentJobPostId) {
      payload.jobPostId = currentJobPostId;
    }

    return payload;
  }, [questions, testId]);

  const submitOnExit = useCallback(() => {
    if (hasSubmittedRef.current || isExitSubmittingRef.current) return;
    if (!routerRef.current?.isReady) return;
    if (loading || error) return;

    const payload = buildSubmitPayload();
    const hasAtLeastOneAnswer = Object.keys(payload.answers || {}).length > 0;
    if (!hasAtLeastOneAnswer) return;

    isExitSubmittingRef.current = true;
    hasSubmittedRef.current = true;

    try {
      submitTestRef.current(payload).catch(() => {});

      clearExamAnswersRef.current("skill");
    } catch {
      // ignore — page is closing
    }
  }, [buildSubmitPayload, error, loading]);

  useEffect(() => {
    if (authLoading) return;

    if (!isAuthenticated) {
      router.push("/login");
      return;
    }

    // Check if user is a candidate
    if (userRole && userRole.toLowerCase() !== "candidate") {
      router.push("/dashboard");
      return;
    }

    if (!router.isReady) return;

    // Extract job and exam context from URL query
    const jobId = router.query.jobId ? Number(router.query.jobId) : null;
    const examIdParam = router.query.examId
      ? Number(router.query.examId)
      : null;

    setJobPostId(jobId);
    setExamId(examIdParam);

    // testId here is actually the performanceId passed from job details
    if (!testId) {
      setError("Invalid test ID.");
      setLoading(false);
      return;
    }

    setPerformanceId(testId);

    let mounted = true;

    (async () => {
      try {
        setLoading(true);
        setError(null);

        // Check submission rules based on whether this is a job-specific test
        if (jobId) {
          // This is a job-specific test - prevent multiple submissions
          try {
            const existingResults = await getResults();
            const examIdToCheck = examIdParam || testId;

            // Find if this exam has already been completed for this specific job
            const existingResult = existingResults.find(
              (result: any) =>
                result.examId === examIdToCheck &&
                result.status === "COMPLETED",
            );

            if (existingResult) {
              // Redirect to results page
              router.push(
                `/dashboard/skill-test/result?resultId=${existingResult.id}&jobId=${jobId}`,
              );
              return;
            }
          } catch (resultsErr: any) {
            console.warn(
              "Failed to check existing results, continuing with exam load:",
              resultsErr,
            );
            // Continue loading the exam even if we can't check results
          }
        }

        // Start the test to establish session and get exam data
        const examIdToFetch = examIdParam || testId;
        let examDataFromStart: any = null;

        // Call startTest to ensure session is established
        if (!startTestCalledRef.current) {
          startTestCalledRef.current = true;
          try {
            console.log("Calling startTest with:", {
              skillExamId: examIdToFetch,
              jobPostId: jobId,
            });
            const startResp = await startTest({
              skillExamId: examIdToFetch,
              ...(jobId && { jobPostId: jobId }),
            });
            console.log("startTest response:", startResp);

            // Update performanceId if returned
            const pid = startResp?.performanceId ?? null;
            if (pid && pid !== performanceId) {
              setPerformanceId(Number(pid));
            }

            // Try to get exam data from startTest response
            examDataFromStart = startResp?.exam;
            console.log("Exam data from startTest:", examDataFromStart);
          } catch (startErr: any) {
            console.warn("startTest failed, but continuing:", startErr);
            // Don't return error here, try to continue with other methods
          }
        }

        // Get exam data - try multiple sources
        let data = examDataFromStart;

        if (!data) {
          // Try to get exam data from localStorage
          const examContext = localStorage.getItem("examContext");
          console.log("Exam context from localStorage:", examContext);
          if (examContext) {
            try {
              const context = JSON.parse(examContext);
              if (context.examData && context.examId === examIdToFetch) {
                data = context.examData;
                console.log("Using exam data from localStorage:", data);
              }
            } catch (e) {
              console.warn(
                "Failed to parse exam context from localStorage:",
                e,
              );
            }
          }
        }

        if (!data) {
          // Final fallback: Get exam details via API
          console.log(
            "Fetching exam data via getTest API for examId:",
            examIdToFetch,
          );
          try {
            // Try getTest first
            data = await getTest(examIdToFetch);
            console.log("Exam data from getTest API:", data);

            // Extract duration if available
            if (data && data.duration) {
              setExamDuration(data.duration);
            }
          } catch (getTestErr: any) {
            console.warn(
              "getTest API failed, trying getExams fallback:",
              getTestErr,
            );

            // Fallback: Get all exams and filter for the specific one
            try {
              console.log(
                "Attempting getExams fallback for examId:",
                examIdToFetch,
              );
              const allExams = await getExams();
              console.log("All exams fetched:", allExams);
              console.log("Looking for exam with ID:", examIdToFetch);

              // Try different ID matching approaches
              data = allExams.find((exam: any) => {
                console.log(
                  "Checking exam:",
                  exam.id,
                  typeof exam.id,
                  exam.name,
                );
                const examIdNum = Number(examIdToFetch);
                const examIdStr = String(examIdToFetch);
                return (
                  exam.id === examIdToFetch ||
                  exam.id === examIdNum ||
                  exam.id === examIdStr ||
                  String(exam.id) === examIdStr
                );
              });

              console.log("Found exam via getExams fallback:", data);

              if (!data) {
                console.error(
                  "Exam not found in list. Available exam IDs:",
                  allExams.map((e: any) => e.id),
                );
                throw new Error(
                  `Exam with ID ${examIdToFetch} not found in exam list`,
                );
              }
            } catch (getExamsErr: any) {
              console.error("Both getTest and getExams failed:", getExamsErr);
              const errorMsg =
                getTestErr?.response?.data?.message ||
                getExamsErr?.response?.data?.message ||
                getTestErr?.message ||
                getExamsErr?.message ||
                "Failed to load exam questions";
              setError(errorMsg);
              setLoading(false);
              return;
            }
          }
        }

        if (!mounted) return;

        // Normalize and accept several possible server response shapes:
        let questionsArray: any[] = [];

        if (!data) {
          questionsArray = [];
        } else if (Array.isArray(data.questions) && data.questions.length > 0) {
          questionsArray = data.questions;
          console.log(
            "Found questions in data.questions:",
            questionsArray.length,
          );
        } else if (
          data.skillQuestionLibrary &&
          Array.isArray(data.skillQuestionLibrary.questions) &&
          data.skillQuestionLibrary.questions.length > 0
        ) {
          questionsArray = data.skillQuestionLibrary.questions;
          console.log(
            "Found questions in data.skillQuestionLibrary.questions:",
            questionsArray.length,
          );
        } else if (
          (data as any).exam &&
          Array.isArray((data as any).exam.questions) &&
          (data as any).exam.questions.length > 0
        ) {
          questionsArray = (data as any).exam.questions;
        } else if (data.questions && typeof data.questions === "object") {
          // convert keyed object to array
          questionsArray = Object.values(data.questions);
        } else {
          questionsArray = [];
        }

        if (!questionsArray || questionsArray.length === 0) {
          console.error("No questions found in exam data");
          setError("No questions found in this test.");
          setLoading(false);
          return;
        }

        setQuestions(questionsArray);

        // Set examId from fetched exam data if not already set
        if (!examId && data?.id) {
          console.log("Setting examId from fetched data:", data.id);
          setExamId(data.id);
        } else {
          console.log("examId already set or no data.id:", {
            examId,
            dataId: data?.id,
          });
        }

        // Set duration from exam data if not already set via getTest
        if (data?.duration && !examDuration) {
          setExamDuration(data.duration);
        }

        // Extract unique topics from questions
        const topicsMap = new Map<string, Topic>();
        let topicIdCounter = 1;

        questionsArray.forEach((question: any) => {
          const topicName = question.topic;

          if (topicName && typeof topicName === "string") {
            if (!topicsMap.has(topicName)) {
              topicsMap.set(topicName, {
                id: topicIdCounter++,
                name: topicName,
              });
            }
          }
        });

        const uniqueTopics = Array.from(topicsMap.values());
        console.log("Extracted topics:", uniqueTopics);
        setTopics(uniqueTopics);

        // Set current topic based on first question
        if (questionsArray.length > 0 && questionsArray[0].topic) {
          const firstTopicName = questionsArray[0].topic;
          const firstTopic = topicsMap.get(firstTopicName);
          if (firstTopic) {
            setCurrentTopicId(firstTopic.id);
          }
        }
      } catch (err: any) {
        if (!mounted) return;
        const errorMsg =
          err?.response?.data?.message ||
          err?.message ||
          "Failed to load test questions";
        setError(errorMsg);
      } finally {
        if (mounted) setLoading(false);
      }
    })();

    return () => {
      mounted = false;
    };
  }, [testId, router.isReady, authLoading, isAuthenticated, userRole, router]);

  // Load saved answers when questions are loaded
  useEffect(() => {
    if (questions.length > 0) {
      // Try to load with examId first, then testId as fallback
      let savedAnswers = null;
      let storageExamId = null;

      if (examId) {
        console.log("Trying to load saved answers for examId:", examId);
        savedAnswers = loadExamAnswers(examId, "skill", user?.id);
        if (savedAnswers) {
          storageExamId = examId;
        }
      }

      // If no answers found with examId, try with testId
      if (!savedAnswers && testId) {
        console.log("Trying to load saved answers for testId:", testId);
        savedAnswers = loadExamAnswers(testId, "skill", user?.id);
        if (savedAnswers) {
          storageExamId = testId;
          // Migrate answers to use examId if available
          if (examId && examId !== testId) {
            console.log("Migrating answers from testId to examId");
            saveExamAnswers(
              examId,
              "skill",
              savedAnswers,
              performanceId,
              user?.id,
            );
            clearExamAnswers("skill"); // Clear old data
          }
        }
      }

      if (savedAnswers) {
        console.log(
          "Loading saved answers:",
          savedAnswers,
          "from examId:",
          storageExamId,
        );
        // Convert saved answers object to Answer array format
        const answersArray: Answer[] = Object.entries(savedAnswers).map(
          ([questionId, optionId]) => ({
            questionId: Number(questionId),
            optionId: optionId as string | number,
          }),
        );
        setAnswers(sanitizeAnswersByQuestions(answersArray, questions));
      } else {
        console.log("No saved answers found");
      }
    } else {
      console.log("Not loading from localStorage - no questions loaded");
    }
  }, [
    questions.length,
    examId,
    testId,
    user?.id,
    loadExamAnswers,
    saveExamAnswers,
    performanceId,
  ]);

  // Save answers to localStorage whenever answers change
  useEffect(() => {
    const sanitizedAnswers = sanitizeAnswersByQuestions(answers, questions);
    if (sanitizedAnswers.length > 0) {
      // Always save with the most specific ID available
      const storageExamId = examId || testId;
      if (storageExamId) {
        const answersObject: Record<string, any> = {};
        sanitizedAnswers.forEach((answer) => {
          answersObject[String(answer.questionId)] = answer.optionId;
        });
        console.log(
          "Saving answers to localStorage:",
          answersObject,
          "for examId:",
          storageExamId,
        );
        saveExamAnswers(
          storageExamId,
          "skill",
          answersObject,
          performanceId,
          user?.id,
        );
      } else {
        console.log(
          "Not saving to localStorage - no examId or testId available",
        );
      }
    } else {
      console.log("Not saving to localStorage - no answers");
    }
  }, [
    answers,
    questions,
    examId,
    testId,
    performanceId,
    user?.id,
    saveExamAnswers,
  ]);

  // Update current topic when question changes
  useEffect(() => {
    if (
      questions.length > 0 &&
      questions[currentQuestionIndex] &&
      topics.length > 0
    ) {
      const currentQuestion = questions[currentQuestionIndex];
      const topicName = currentQuestion.topic;

      if (topicName && typeof topicName === "string") {
        const matchedTopic = topics.find((t) => t.name === topicName);
        if (matchedTopic) {
          setCurrentTopicId(matchedTopic.id);
        }
      }
    }
  }, [currentQuestionIndex, questions, topics]);

  // Auto-submit when candidate exits in between exam.
  useEffect(() => {
    if (!router.isReady) return;

    const handleBeforeUnload = () => {
      submitOnExit();
    };

    const handlePageHide = () => {
      submitOnExit();
    };

    const handleRouteChangeStart = (url: string) => {
      const currentPath = router.asPath || "";
      if (url !== currentPath) {
        submitOnExit();
      }
    };

    window.addEventListener("beforeunload", handleBeforeUnload);
    window.addEventListener("pagehide", handlePageHide);
    router.events.on("routeChangeStart", handleRouteChangeStart);

    return () => {
      window.removeEventListener("beforeunload", handleBeforeUnload);
      window.removeEventListener("pagehide", handlePageHide);
      router.events.off("routeChangeStart", handleRouteChangeStart);
    };
  }, [router, submitOnExit]);

  // Anti-cheat: Auto-submit when candidate switches tabs
  useEffect(() => {
    if (!router.isReady || loading || error) return;

    const handleVisibilityChange = () => {
      if (document.hidden) {
        console.log("[Anti-cheat] Tab switch detected — auto-submitting exam");
        submitOnExit();
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);

    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  }, [router.isReady, loading, error, submitOnExit]);

  // Anti-cheat: Fullscreen enforcement
  useEffect(() => {
    if (!router.isReady || loading || error || questions.length === 0) return;

    // Request fullscreen when exam loads
    const requestFullscreen = async () => {
      try {
        if (!document.fullscreenElement) {
          await document.documentElement.requestFullscreen();
          console.log("[Anti-cheat] Entered fullscreen mode");
        }
      } catch (err) {
        console.warn("[Anti-cheat] Fullscreen request failed:", err);
        // Don't block the exam if fullscreen is denied (e.g., mobile browsers)
      }
    };

    requestFullscreen();

    const handleFullscreenChange = () => {
      if (!document.fullscreenElement && !hasSubmittedRef.current) {
        console.log("[Anti-cheat] Exited fullscreen — auto-submitting exam");
        submitOnExit();
      }
    };

    document.addEventListener("fullscreenchange", handleFullscreenChange);

    return () => {
      document.removeEventListener("fullscreenchange", handleFullscreenChange);
      // Exit fullscreen on cleanup (unmount)
      if (document.fullscreenElement) {
        document.exitFullscreen().catch(() => {});
      }
    };
  }, [router.isReady, loading, error, questions.length, submitOnExit]);

  // Auto-submission when time is up.
  //
  // KEY FIX: We only depend on `examDuration` here. All other values
  // (router, submitTest, clearExamAnswers, jobPostId, performanceId, answers)
  // are accessed via refs so that:
  //   1. The timer is never reset when those references change between renders.
  //   2. The callback always reads the *latest* values at the moment it fires
  //      (no stale closure problem).
  //   3. timerStartedRef prevents a second timer being created even if
  //      examDuration is set, cleared, then re-set.
  useEffect(() => {
    if (!examDuration || examDuration <= 0 || timerStartedRef.current) return;

    timerStartedRef.current = true;
    console.log(
      `[Timer] Started — will fire in ${examDuration} minute(s) (${examDuration * 60 * 1000} ms)`,
    );

    const timer = setTimeout(
      async () => {
        console.log("[Timer] Fired — auto-submitting exam");

        await Swal.fire({
          icon: "info",
          title: "Time's Up!",
          text: "The exam time has expired. Your answers will be submitted automatically.",
          timer: 3000,
          showConfirmButton: false,
        });

        // Read latest values from refs — never stale
        const currentAnswers = answersRef.current;
        const currentPerformanceId = performanceIdRef.current;
        const currentJobPostId = jobPostIdRef.current;

        try {
          if (hasSubmittedRef.current) {
            return;
          }
          hasSubmittedRef.current = true;
          setSubmitting(true);

          // Validate that all answers have valid optionIds
          const validAnswers = sanitizeAnswersByQuestions(
            currentAnswers,
            questions,
          );

          const answersObject: Record<string, string | number> = {};
          validAnswers.forEach((a) => {
            answersObject[String(a.questionId)] = a.optionId;
          });

          const payload: any = {
            performanceId: currentPerformanceId || testId,
            answers: answersObject,
          };

          // Include job context if available
          if (currentJobPostId) {
            payload.jobPostId = currentJobPostId;
          }

          console.log("[Timer] Auto-submitting with payload:", payload);

          // Use refs so this closure never captures a stale function reference
          const res = await submitTestRef.current(payload);

          // Clear localStorage answers after successful submission
          clearExamAnswersRef.current("skill");

          const submittedPerformanceId =
            res.performance?.id || res.data?.performance?.id;

          if (submittedPerformanceId) {
            routerRef.current.push(
              `/dashboard/skill-test/result?performanceId=${submittedPerformanceId}${currentJobPostId ? `&jobId=${currentJobPostId}` : ""}`,
            );
          } else {
            routerRef.current.push(
              `/dashboard/skill-test/result${currentJobPostId ? `?jobId=${currentJobPostId}` : ""}`,
            );
          }
        } catch (err: any) {
          hasSubmittedRef.current = false;
          console.error("[Timer] Auto-submit failed:", err);
          await Swal.fire({
            icon: "error",
            title: "Submission Error",
            text: "Failed to submit your exam automatically. Please try submitting manually.",
          });
          setSubmitting(false);
        }
      },
      examDuration * 60 * 1000,
    );

    // Cleanup only runs on unmount — NOT on every re-render — because
    // examDuration is stable once set and timerStartedRef prevents re-entry.
    return () => {
      console.log("[Timer] Cleared on unmount");
      clearTimeout(timer);
    };
  }, [examDuration]); // eslint-disable-line react-hooks/exhaustive-deps
  // ^ Intentionally omitting router, submitTest, clearExamAnswers, testId etc.
  //   from deps — they are accessed via refs above. Adding them would cause the
  //   timer to reset on every render in production.

  const handleAnswerChange = (
    questionId: number,
    optionKey: string | number | null | undefined,
  ) => {
    console.log("handleAnswerChange called:", { questionId, optionKey });

    // Validate that optionKey is not null or undefined
    if (optionKey === null || optionKey === undefined || optionKey === "") {
      console.log("Invalid optionKey, returning");
      return;
    }

    // Find the question
    const question = questions.find((q) => q.id === questionId);
    if (!question) {
      console.log("Question not found for id:", questionId);
      return;
    }

    // Get the actual option ID using the helper function
    const optionId = getOptionIdFromKey(question, optionKey);

    if (optionId === null) {
      return;
    }

    setAnswers((prev) => {
      const copy = [...prev];
      const idx = copy.findIndex((a) => a.questionId === questionId);

      if (idx > -1) {
        copy[idx] = { questionId, optionId };
        console.log("Updated existing answer:", { questionId, optionId });
      } else {
        copy.push({ questionId, optionId });
        console.log("Added new answer:", { questionId, optionId });
      }

      console.log("New answers state:", copy);
      return copy;
    });
  };

  // Helper function to map option letters (A, B, C, D) to option IDs
  const getOptionIdFromKey = (
    question: any,
    optionKey: string | number,
  ): number | null => {
    if (!question) return null;

    let optionsArray: any[] = [];

    // Handle different option formats
    if (Array.isArray(question.options)) {
      optionsArray = question.options;
    } else if (typeof question.options === "object") {
      optionsArray = Object.entries(question.options).map(
        ([key, value]: any) => ({
          key,
          value,
          id: value?.id || key,
        }),
      );
    }

    // Try to find the option
    // First, try matching by key (A, B, C, D)
    let option = optionsArray.find((opt: any) => opt.key === optionKey);

    // If not found, try matching by index (0, 1, 2, 3)
    if (!option && typeof optionKey === "string") {
      const letterIndex = optionKey.charCodeAt(0) - 65; // A=0, B=1, C=2, D=3
      if (letterIndex >= 0 && letterIndex < optionsArray.length) {
        option = optionsArray[letterIndex];
      }
    }

    // If still not found, try direct match
    if (!option) {
      option = optionsArray.find(
        (opt: any) => opt.id === optionKey || opt.value === optionKey,
      );
    }

    if (!option) {
      return null;
    }

    // Return the option ID
    return option.id || option.value?.id || optionKey;
  };

  const handleNext = () =>
    setCurrentQuestionIndex((i) => Math.min(i + 1, questions.length - 1));
  const handlePrev = () => setCurrentQuestionIndex((i) => Math.max(i - 1, 0));

  const handleTopicClick = (topicId: number) => {
    // Find the first question with this topic
    const topicToFind = topics.find((t) => t.id === topicId);
    if (!topicToFind) return;

    const firstQuestionIndex = questions.findIndex(
      (q) => q.topic === topicToFind.name,
    );
    if (firstQuestionIndex !== -1) {
      setCurrentQuestionIndex(firstQuestionIndex);
      setCurrentTopicId(topicId);
    }
  };

  const handleSubmit = async () => {
    try {
      const isSure = await Swal.fire({
        title: "Submit Test?",
        text: "Are you sure you want to submit your answers? You won't be able to change them after submission.",
        icon: "warning",
        showCancelButton: true,
        confirmButtonColor: "#3085d6",
        cancelButtonColor: "#d33",
        confirmButtonText: "Yes, submit!",
        cancelButtonText: "Cancel",
      });
      if (!isSure.isConfirmed) {
        return;
      }

      if (hasSubmittedRef.current) {
        return;
      }
      hasSubmittedRef.current = true;
      setSubmitting(true);

      // Validate that all answers have valid optionIds
      const validAnswers = sanitizeAnswersByQuestions(answers, questions);

      const answersObject: Record<string, string | number> = {};
      validAnswers.forEach((a) => {
        answersObject[String(a.questionId)] = a.optionId;
      });

      const payload: any = {
        performanceId: performanceId || testId,
        answers: answersObject,
      };

      // Include job context if available
      if (jobPostId) {
        payload.jobPostId = jobPostId;
      }

      const res = await submitTest(payload);

      // Clear localStorage answers after successful submission
      clearExamAnswers("skill");

      const submittedPerformanceId =
        res.performance?.id || res.data?.performance?.id;

      if (submittedPerformanceId) {
        router.push(
          `/dashboard/skill-test/result?performanceId=${submittedPerformanceId}${jobPostId ? `&jobId=${jobPostId}` : ""}`,
        );
      } else {
        router.push(
          `/dashboard/skill-test/result${jobPostId ? `?jobId=${jobPostId}` : ""}`,
        );
      }
    } catch (err: any) {
      hasSubmittedRef.current = false;
      // Check for specific error messages
      const errorResponse = err?.response?.data;
      let errorMsg = "Failed to submit exam";

      if (errorResponse?.message) {
        errorMsg = errorResponse.message;
      } else if (errorResponse?.errors && Array.isArray(errorResponse.errors)) {
        errorMsg = errorResponse.errors[0]?.message || errorMsg;
      } else if (err?.message) {
        errorMsg = err.message;
      }

      // Handle "already submitted" error based on test type
      if (
        errorMsg.includes("already been submitted") ||
        errorMsg.includes("cannot be resubmitted")
      ) {
        if (jobPostId) {
          // Job-specific test - this error is expected, redirect to results
          await Swal.fire({
            icon: "info",
            title: "Test Already Submitted",
            text: "You have already submitted this job-specific skill test. Redirecting to your results...",
          });
          router.push(
            `/dashboard/skill-test/result?jobId=${jobPostId}&testId=${testId}`,
          );
          return;
        } else {
          // General skill test - allow multiple submissions, show different message
          await Swal.fire({
            icon: "info",
            title: "Test Already Taken",
            text: "You have already taken this skill test. You can retake general skill tests multiple times. Redirecting to your results...",
          });
          router.push(`/dashboard/skill-test/result?testId=${testId}`);
          return;
        }
      }

      await Swal.fire({
        icon: "error",
        title: "Error",
        text: errorMsg,
      });
      setSubmitting(false);
    }
  };

  const currentQuestion = questions[currentQuestionIndex];
  const answeredCount = sanitizeAnswersByQuestions(answers, questions).length;
  const progressPercent =
    questions.length > 0
      ? Math.round(((currentQuestionIndex + 1) / questions.length) * 100)
      : 0;
  const isAnswered = answers.some((a) => a.questionId === currentQuestion?.id);

  // Get the selected answer for the current question
  const currentAnswer = answers.find(
    (a) => a.questionId === currentQuestion?.id,
  );

  if (loading) {
    return (
      <>
        <Seo pageTitle="Skill Test" />
        <div className="page-wrapper dashboard psychometric_questions_wrapper">
          <span className="header-span"></span>
          <PsychometricHeader />
          <PsychometricSidebar
            activeId={currentTopicId}
            topics={topics}
            getIsSidebarOpen={getIsSidebarOpen}
            setIsSidebarOpen={setIsSidebarOpen}
            onTopicClick={handleTopicClick}
          />
          <section className="user-dashboard">
            <div className="dashboard-outer">
              <div className="row">
                <div className="col-lg-12">
                  <div className="ls-widget">
                    <div className="tabs-box">
                      <div className="widget-content text-center py-8">
                        <div className="spinner mb-4"></div>
                        <p>Loading test questions...</p>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>
          <CopyrightFooter />
        </div>
      </>
    );
  }

  if (error || questions.length === 0) {
    return (
      <>
        <Seo pageTitle="Error - Test" />
        <div className="page-wrapper dashboard psychometric_questions_wrapper">
          <span className="header-span"></span>
          <PsychometricHeader />
          <PsychometricSidebar
            activeId={currentTopicId}
            topics={topics}
            getIsSidebarOpen={getIsSidebarOpen}
            setIsSidebarOpen={setIsSidebarOpen}
            onTopicClick={handleTopicClick}
          />
          <section className="user-dashboard">
            <div className="dashboard-outer">
              <BreadCrumb
                title="Skill Test"
                getIsSidebarOpen={getIsSidebarOpen}
                setIsSidebarOpen={setIsSidebarOpen}
              />
              <div className="row">
                <div className="col-lg-12">
                  <div className="ls-widget">
                    <div className="tabs-box">
                      <div className="widget-content">
                        <div className="alert alert-danger">
                          {error || "No questions available"}
                        </div>
                        <button
                          className="theme-btn btn-style-one d-inline-block"
                          onClick={() =>
                            jobPostId
                              ? router.push(`/jobs/${jobPostId}`)
                              : router.back()
                          }
                        >
                          Go Back
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>
          <CopyrightFooter />
        </div>
      </>
    );
  }

  return (
    <>
      <Seo pageTitle={`Question ${currentQuestionIndex + 1}`} />
      <div className="page-wrapper dashboard psychometric_questions_wrapper">
        <span className="header-span"></span>
        <PsychometricHeader />
        <PsychometricSidebar
          activeId={currentTopicId}
          topics={topics}
          getIsSidebarOpen={getIsSidebarOpen}
          setIsSidebarOpen={setIsSidebarOpen}
          onTopicClick={handleTopicClick}
          examDuration={examDuration}
        />
        <section className="user-dashboard">
          <div className="dashboard-outer">
            <BreadCrumb
              title="Skill Test"
              getIsSidebarOpen={getIsSidebarOpen}
              setIsSidebarOpen={setIsSidebarOpen}
            />
            <div className="row">
              <div className="col-lg-12">
                <div className="ls-widget">
                  <div className="tabs-box">
                    <div className="mb-4">
                      <div
                        style={{
                          display: "flex",
                          justifyContent: "space-between",
                          marginBottom: "8px",
                        }}
                      >
                        <span style={{ fontSize: "14px", fontWeight: "600" }}>
                          Progress
                        </span>
                        <span style={{ fontSize: "14px", fontWeight: "600" }}>
                          {progressPercent}%
                        </span>
                      </div>
                      <div
                        style={{
                          width: "100%",
                          backgroundColor: "#e0e0e0",
                          borderRadius: "8px",
                          height: "8px",
                        }}
                      >
                        <div
                          style={{
                            backgroundColor: "#146e79ff",
                            height: "8px",
                            borderRadius: "8px",
                            width: `${progressPercent}%`,
                            transition: "width 0.3s ease",
                          }}
                        ></div>
                      </div>
                    </div>

                    <div className="widget-title">
                      <h4>
                        Question {currentQuestionIndex + 1} of{" "}
                        {questions.length}
                        {isAnswered && (
                          <span
                            style={{ color: "#28a839ff", marginLeft: "8px" }}
                          >
                            ✓
                          </span>
                        )}
                      </h4>
                    </div>
                    <div className="widget-content">
                      {currentQuestion && (
                        <PsychometricQuestion
                          question={currentQuestion}
                          questionNo={currentQuestionIndex + 1}
                          onAnswerChange={handleAnswerChange}
                          selectedAnswer={currentAnswer?.optionId}
                        />
                      )}
                      <div
                        style={{
                          display: "flex",
                          justifyContent: "space-between",
                          paddingTop: "24px",
                          paddingBottom: "24px",
                          gap: "12px",
                          flexWrap: "wrap",
                        }}
                      >
                        <button
                          className="theme-btn btn-style-one d-inline-block"
                          onClick={handlePrev}
                          disabled={currentQuestionIndex === 0}
                          style={{
                            opacity: currentQuestionIndex === 0 ? 0.6 : 1,
                            cursor:
                              currentQuestionIndex === 0
                                ? "not-allowed"
                                : "pointer",
                          }}
                        >
                          Previous
                        </button>
                        {currentQuestionIndex < questions.length - 1 ? (
                          <button
                            className="theme-btn btn-style-one d-inline-block"
                            onClick={handleNext}
                          >
                            Next
                          </button>
                        ) : (
                          <button
                            className="theme-btn btn-style-one d-inline-block bg-green-600 hover:bg-green-700"
                            onClick={handleSubmit}
                            disabled={submitting}
                          >
                            {submitting ? "Submitting..." : "Submit Test"}
                          </button>
                        )}
                      </div>
                      <p style={{ fontSize: "14px", fontWeight: "600" }}>
                        Answered: {answeredCount} of {questions.length}{" "}
                        questions
                      </p>
                      <div
                        style={{
                          width: "100%",
                          backgroundColor: "#e0e0e0",
                          borderRadius: "8px",
                          height: "8px",
                          marginTop: "8px",
                        }}
                      >
                        <div
                          style={{
                            backgroundColor: "#28a745",
                            height: "8px",
                            borderRadius: "8px",
                            width: `${(answers.length / questions.length) * 100}%`,
                          }}
                        ></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
        <CopyrightFooter />
      </div>
    </>
  );
};

export default SkillTakePage;
