"use client";

import { useState, useEffect } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { scoreQuestion } from "@/lib/scoring";
import { QuizResults } from "./QuizResults";

interface Option {
  id: string;
  text: string;
  isCorrect: boolean;
}

interface Question {
  id: string;
  type: string;
  prompt: string;
  rationale: string;
  category: string;
  options: Option[];
}

interface QuizViewerProps {
  quiz: {
    id: string;
    name: string;
    questions: Question[];
    progress: Array<{
      mode: string;
      currentIndex: number;
      orderJson: string;
      answersJson: string | null;
    }>;
  };
  retakeIds: string[] | null;
  isShared?: boolean;
  onFinished: () => void;
}

export function QuizViewer({ quiz, retakeIds, isShared = false, onFinished }: QuizViewerProps) {
  const [order, setOrder] = useState<string[]>([]);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [answers, setAnswers] = useState<Record<string, string[]>>({});
  const [submittedAnswers, setSubmittedAnswers] = useState<string[]>([]);
  const [shuffledOptions, setShuffledOptions] = useState<Record<string, Option[]>>({});
  
  const [loading, setLoading] = useState(true);
  const [resultsData, setResultsData] = useState<any | null>(null);

  // Initialize session
  useEffect(() => {
    // Generate shuffled options once per session mount
    const newShuffledOpts: Record<string, Option[]> = {};
    for (const q of quiz.questions) {
      newShuffledOpts[q.id] = [...q.options].sort(() => Math.random() - 0.5);
    }
    setShuffledOptions(newShuffledOpts);

    // If retaking specific questions
    if (retakeIds && retakeIds.length > 0) {
      setOrder(retakeIds);
      setCurrentIndex(0);
      setAnswers({});
      setSubmittedAnswers([]);
      setLoading(false);
      return;
    }

    // Otherwise, normal sequential logic checking for progress
    const prog = quiz.progress?.find((p) => p.mode === "SEQUENTIAL");
    if (prog) {
      let savedOrder: string[] = [];
      try {
        savedOrder = JSON.parse(prog.orderJson);
      } catch {
        savedOrder = quiz.questions.map((q) => q.id);
      }

      let savedAnswers: Record<string, string[]> = {};
      if (prog.answersJson) {
        try {
          savedAnswers = JSON.parse(prog.answersJson);
        } catch {}
      }

      setOrder(savedOrder);
      setCurrentIndex(Math.min(prog.currentIndex, savedOrder.length - 1));
      setAnswers(savedAnswers);
      setSubmittedAnswers(Object.keys(savedAnswers));
    } else {
      const freshOrder = quiz.questions.map((q) => q.id).sort(() => Math.random() - 0.5);
      setOrder(freshOrder);
      setCurrentIndex(0);
      setAnswers({});
      setSubmittedAnswers([]);
    }
    setLoading(false);
  }, [quiz, retakeIds]);

  // Persist progress as you go
  function saveProgress(
    idx: number,
    ans: Record<string, string[]>
  ) {
    if (retakeIds || isShared) return; // Don't persist retake partial state or shared mode into the main progress row

    fetch("/api/progress", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        contentType: "QUIZ",
        contentId: quiz.id,
        mode: "SEQUENTIAL",
        currentIndex: idx,
        orderJson: JSON.stringify(order),
        answersJson: JSON.stringify(ans),
      }),
    }).catch(() => {});
  }

  if (loading) return <div>Loading quiz...</div>;

  const currentQId = order[currentIndex];
  const currentQ = quiz.questions.find((q) => q.id === currentQId);
  const isSubmitted = currentQId ? submittedAnswers.includes(currentQId) : false;
  const currentSelections = currentQId ? answers[currentQId] || [] : [];

  // Compute running score
  let runningScore = 0;
  let maxPossibleSoFar = 0;
  
  submittedAnswers.forEach((qId) => {
    const q = quiz.questions.find((x) => x.id === qId);
    if (!q) return;
    maxPossibleSoFar += 1; // 1 point per question
    const formattedQ = {
      id: q.id,
      type: q.type as "MULTIPLE_CHOICE" | "SATA",
      options: q.options,
    };
    runningScore += scoreQuestion(formattedQ, answers[qId] || []);
  });

  function toggleOption(optId: string) {
    if (isSubmitted || !currentQId || !currentQ) return;
    
    if (currentQ.type === "MULTIPLE_CHOICE") {
      setAnswers({ ...answers, [currentQId]: [optId] });
    } else {
      const prev = answers[currentQId] || [];
      const updated = prev.includes(optId)
        ? prev.filter((id) => id !== optId)
        : [...prev, optId];
      setAnswers({ ...answers, [currentQId]: updated });
    }
  }

  function handleSubmit() {
    if (isSubmitted || !currentQId) return;
    const newSubmitted = [...submittedAnswers, currentQId];
    setSubmittedAnswers(newSubmitted);
    saveProgress(currentIndex, answers);
  }

  function handleNext() {
    if (currentIndex + 1 < order.length) {
      const nextIdx = currentIndex + 1;
      setCurrentIndex(nextIdx);
      saveProgress(nextIdx, answers);
    }
  }

  async function handleFinish() {
    // If shared, grade it locally and show results, don't ping backend
    if (isShared) {
      // Simulate an attempt object
      let runningScore = 0;
      let maxScore = quiz.questions.length; // Actually, depends on retakeIds, but shared doesn't support retakeIds typically
      if (retakeIds) maxScore = retakeIds.length;
      
      const scoredItems = (retakeIds || quiz.questions.map(q => q.id)).map(qId => {
        const q = quiz.questions.find((x) => x.id === qId);
        if (!q) return 0;
        const formattedQ = {
          id: q.id,
          type: q.type as "MULTIPLE_CHOICE" | "SATA",
          options: q.options,
        };
        return scoreQuestion(formattedQ, answers[qId] || []);
      });
      runningScore = scoredItems.reduce((acc, curr) => acc + curr, 0);

      const attempt = {
        id: "shared-attempt",
        score: runningScore,
        maxScore: maxScore,
        answersJson: JSON.stringify(answers),
        isPartialRetake: false,
        completedAt: new Date().toISOString(),
      };
      setResultsData(attempt);
      return;
    }

    // Send to backend
    const isPartialRetake = !!retakeIds;
    try {
      const res = await fetch(`/api/quizzes/${quiz.id}/attempt`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          answersJson: JSON.stringify(answers),
          isPartialRetake,
        }),
      });

      if (res.ok) {
        const attempt = await res.json();
        
        // Clear progress
        if (!isPartialRetake) {
          await fetch("/api/progress", {
            method: "DELETE",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              contentType: "QUIZ",
              contentId: quiz.id,
              mode: "SEQUENTIAL",
            }),
          });
        }
        
        setResultsData(attempt);
      }
    } catch (e) {
      console.error(e);
    }
  }

  if (resultsData) {
    return (
      <QuizResults
        quiz={quiz}
        attempt={resultsData}
        onRetake={(missedIds: string[]) => {
          // Restart this component with retakeIds
          setOrder(missedIds);
          setCurrentIndex(0);
          setAnswers({});
          setSubmittedAnswers([]);
          setResultsData(null);
        }}
        onClose={onFinished}
      />
    );
  }

  if (!currentQ) {
    return <div>Question not found.</div>;
  }

  return (
    <div className="flex flex-col items-center">
      {/* Running Score Header */}
      <div className="w-full max-w-2xl mb-6 flex items-center justify-between bg-bg-surface border border-border-light rounded-lg px-5 py-3 shadow-[var(--shadow-card)]">
        <div>
          <span className="text-sm font-medium text-text-secondary">Progress: </span>
          <span className="text-sm font-bold text-text-heading">{currentIndex + 1} / {order.length}</span>
        </div>
        <div>
          <span className="text-sm font-medium text-text-secondary">Score so far: </span>
          <span className="text-sm font-bold text-primary">
            {parseFloat(runningScore.toFixed(2))} / {maxPossibleSoFar}
          </span>
        </div>
      </div>

      {/* Question Card */}
      <div className="w-full max-w-2xl bg-bg-surface rounded-2xl border border-border-light shadow-[var(--shadow-card)] overflow-hidden mb-8">
        
        {/* Header (Type & Category) */}
        <div className="bg-bg-surface-alt border-b border-border-light px-6 py-4 flex items-center justify-between">
          <span className="text-xs font-bold uppercase tracking-wider text-primary">
            {currentQ.type === "MULTIPLE_CHOICE" ? "Multiple Choice" : "Select All That Apply"}
          </span>
          <span className="inline-flex px-2.5 py-1 rounded-full bg-badge-bg text-badge-text text-xs font-medium">
            {currentQ.category}
          </span>
        </div>

        <div className="p-6 md:p-8">
          <div className="markdown-content text-lg text-text-heading mb-8 leading-relaxed font-medium">
            <ReactMarkdown remarkPlugins={[remarkGfm]}>
              {currentQ.prompt}
            </ReactMarkdown>
          </div>

          <div className="space-y-3">
            {(shuffledOptions[currentQId] || currentQ.options).map((opt) => {
              const isSelected = currentSelections.includes(opt.id);
              let stateClass = "border-border hover:border-primary/50 cursor-pointer";
              let icon = null;

              if (isSubmitted) {
                stateClass = "cursor-default opacity-80";
                if (opt.isCorrect) {
                  stateClass = "border-success bg-success-bg/30 text-text-heading";
                  icon = (
                    <svg className="w-5 h-5 text-success flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7" />
                    </svg>
                  );
                } else if (isSelected && !opt.isCorrect) {
                  // Selected incorrectly
                  stateClass = "border-error bg-error-bg/30 text-text-heading";
                  icon = (
                    <svg className="w-5 h-5 text-error flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M6 18L18 6M6 6l12 12" />
                    </svg>
                  );
                } else {
                  // Not selected, not correct
                  stateClass = "border-border-light bg-bg-surface-alt/50";
                }
              } else if (isSelected) {
                stateClass = "border-primary bg-primary/5 ring-1 ring-primary";
              }

              return (
                <div
                  key={opt.id}
                  onClick={() => toggleOption(opt.id)}
                  className={`flex items-start gap-4 p-4 rounded-xl border-2 transition-all duration-200 ${stateClass}`}
                >
                  <div className="pt-0.5">
                    <div className={`w-5 h-5 rounded ${currentQ.type === 'SATA' ? 'border' : 'border rounded-full'} flex items-center justify-center transition-colors ${
                      isSelected ? 'border-primary bg-primary text-white' : 'border-border-light bg-bg-surface'
                    }`}>
                      {isSelected && (
                        <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
                        </svg>
                      )}
                    </div>
                  </div>
                  <div className="flex-1 text-text-body font-medium leading-snug">
                    {opt.text}
                  </div>
                  {icon && (
                    <div className="pt-0.5 pl-2">
                      {icon}
                    </div>
                  )}
                </div>
              );
            })}
          </div>

          {/* Rationale shown after submission */}
          {isSubmitted && (() => {
            const formattedQ = {
              id: currentQ.id,
              type: currentQ.type as "MULTIPLE_CHOICE" | "SATA",
              options: currentQ.options,
            };
            const qScore = scoreQuestion(formattedQ, currentSelections);
            let badgeText = "Incorrect";
            let bannerBg = "bg-error/10 border-error/20 text-error";
            let icon = (
              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M6 18L18 6M6 6l12 12" />
              </svg>
            );
            
            if (qScore === 1) {
              badgeText = "Correct";
              bannerBg = "bg-success/10 border-success/20 text-success";
              icon = (
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7" />
                </svg>
              );
            } else if (qScore > 0) {
              badgeText = "Partially Correct";
              bannerBg = "bg-amber-500/10 border-amber-500/20 text-amber-600";
              icon = (
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                </svg>
              );
            }

            return (
              <div className="mt-8 flex flex-col gap-4 animate-slide-up">
                {/* Result Banner */}
                <div className={`flex items-center gap-3 px-5 py-4 rounded-xl border ${bannerBg} font-bold text-lg tracking-wide shadow-sm`}>
                  {icon}
                  {badgeText}
                </div>

                {/* Rationale Box */}
                <div className="bg-bg-callout border border-primary/20 rounded-xl p-5 shadow-sm">
                  <h4 className="text-sm font-bold text-text-heading uppercase tracking-wider mb-2">Rationale</h4>
                  <div className="markdown-content text-sm text-text-body">
                    <ReactMarkdown remarkPlugins={[remarkGfm]}>
                      {currentQ.rationale}
                    </ReactMarkdown>
                  </div>
                </div>
              </div>
            );
          })()}
        </div>

        {/* Action bar */}
        <div className="bg-bg-surface-alt px-6 py-5 border-t border-border-light flex justify-end">
          {!isSubmitted ? (
            <button
              onClick={handleSubmit}
              disabled={currentSelections.length === 0}
              className="px-6 py-2.5 rounded-lg bg-primary text-white font-medium hover:bg-primary-hover disabled:opacity-50 transition-all duration-200 cursor-pointer"
            >
              Submit Answer
            </button>
          ) : currentIndex + 1 < order.length ? (
            <button
              onClick={handleNext}
              className="px-6 py-2.5 rounded-lg bg-text-heading text-white font-medium hover:bg-text-body transition-all duration-200 cursor-pointer"
            >
              Next Question
            </button>
          ) : (
            <button
              onClick={handleFinish}
              className="px-6 py-2.5 rounded-lg bg-success text-white font-medium hover:bg-success/90 transition-all duration-200 cursor-pointer"
            >
              Finish Quiz
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
