"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);
  const [toastMessage, setToastMessage] = useState<string | null>(null);

  // Auto-hide toast
  useEffect(() => {
    if (toastMessage) {
      const timer = setTimeout(() => setToastMessage(null), 3000);
      return () => clearTimeout(timer);
    }
  }, [toastMessage]);

  // 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;
    }

    // Shared links: load from localStorage
    if (isShared) {
      try {
        const saved = localStorage.getItem(`quiz_progress_${quiz.id}`);
        if (saved) {
          const parsed = JSON.parse(saved);
          setOrder(parsed.order || quiz.questions.map(q => q.id));
          setCurrentIndex(parsed.currentIndex || 0);
          setAnswers(parsed.answers || {});
          setSubmittedAnswers(Object.keys(parsed.answers || {}));
          setToastMessage("Session restored");
          setLoading(false);
          return;
        }
      } catch (e) {
        // Fallback to defaults
      }
    }

    // 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, isShared]);

  // Persist progress as you go
  function saveProgress(
    idx: number,
    ans: Record<string, string[]>
  ) {
    if (retakeIds) return; // Don't persist retake partial state

    if (isShared) {
      localStorage.setItem(`quiz_progress_${quiz.id}`, JSON.stringify({
        currentIndex: idx,
        order: order,
        answers: ans,
      }));
      return;
    }

    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 (isShared) {
      localStorage.removeItem(`quiz_progress_${quiz.id}`);
    }
    
    // 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);

          // Re-shuffle options for the new attempt
          const newShuffledOpts: Record<string, Option[]> = {};
          for (const q of quiz.questions) {
            newShuffledOpts[q.id] = [...q.options].sort(() => Math.random() - 0.5);
          }
          setShuffledOptions(newShuffledOpts);
        }}
        onClose={onFinished}
      />
    );
  }

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

  return (
    <div className="flex flex-col items-center relative">
      {/* Toast Notification */}
      {toastMessage && (
        <div className="absolute top-4 left-1/2 -translate-x-1/2 z-30 animate-fade-in pointer-events-none">
          <div className="bg-bg-surface-alt/95 backdrop-blur shadow-[var(--shadow-card)] text-text-heading text-sm font-semibold px-6 py-2.5 rounded-full whitespace-nowrap">
            {toastMessage}
          </div>
        </div>
      )}
      
      {/* Main Unified Card */}
      <div className="mb-8 mt-4 w-full max-w-4xl overflow-hidden rounded-[2rem] border border-border-light bg-bg-surface shadow-[var(--shadow-card-hover)] md:mt-8">
        
        {/* Progress Header */}
        <div className="flex items-center gap-4 border-b border-border-light bg-bg-surface-alt/55 px-5 py-4 md:px-8">
          <div className="text-sm font-mono text-text-secondary whitespace-nowrap tracking-wider">
            Q {currentIndex + 1} / {order.length}
          </div>
          <div className="flex-1 h-2 bg-bg-surface rounded-full overflow-hidden border border-border-light/50">
            <div 
              className="h-full bg-primary transition-all duration-300"
              style={{ width: `${(currentIndex / order.length) * 100}%` }}
            />
          </div>
          <div className="bg-badge-bg/50 px-3 py-1 rounded-full text-sm font-mono text-primary whitespace-nowrap">
            Score: {parseFloat(runningScore.toFixed(2))} / {maxPossibleSoFar}
          </div>
        </div>

        {/* Question Area */}
        <div className="px-5 pb-6 pt-6 md:px-10 md:pb-10 md:pt-8">
          
          {/* Tags */}
          <div className="flex items-center justify-between mb-8">
            <span className="inline-flex px-3 py-1 rounded-md bg-primary/10 text-primary text-xs font-bold uppercase tracking-wider">
              {currentQ.category}
            </span>
            <span className="inline-flex px-3 py-1 rounded-md bg-amber-500/10 text-amber-600 text-xs font-bold uppercase tracking-wider">
              {currentQ.type === "MULTIPLE_CHOICE" ? "Multiple Choice" : "Select All That Apply"}
            </span>
          </div>

          {/* Prompt */}
          <div className="markdown-content editorial-title mb-8 text-2xl leading-relaxed text-text-heading md:text-3xl">
            <ReactMarkdown remarkPlugins={[remarkGfm]}>
              {currentQ.prompt}
            </ReactMarkdown>
          </div>

          {/* Options */}
          <div className="space-y-4">
            {(shuffledOptions[currentQId] || currentQ.options).map((opt) => {
              const isSelected = currentSelections.includes(opt.id);
              let stateClass = "border-border-light hover:border-border cursor-pointer";
              let rightIcon = null;
              
              if (isSubmitted) {
                stateClass = "cursor-default opacity-80";
                if (isSelected && opt.isCorrect) {
                  stateClass = "border-success bg-success-bg text-text-heading";
                } else if (isSelected && !opt.isCorrect) {
                  stateClass = "border-error bg-error-bg text-text-heading";
                } else if (!isSelected && opt.isCorrect) {
                  stateClass = "border-success/50 bg-success/5 text-text-heading";
                  rightIcon = (
                    <div className="text-success flex items-center gap-1.5 text-sm font-bold">
                      <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>
                      Correct Answer
                    </div>
                  );
                } else {
                  stateClass = "border-border-light";
                }
              } else if (isSelected) {
                stateClass = "border-primary bg-primary/5";
              }

              return (
                <div
                  key={opt.id}
                  onClick={() => toggleOption(opt.id)}
                  className={`flex min-h-14 items-center gap-4 rounded-2xl border px-4 py-4 transition-all duration-200 md:px-5 ${stateClass}`}
                >
                  <div className="flex-shrink-0">
                    <div className={`w-5 h-5 rounded ${currentQ.type === 'SATA' ? 'border' : 'border rounded-full'} flex items-center justify-center transition-colors ${
                      isSelected && isSubmitted && opt.isCorrect ? 'border-success bg-success' :
                      isSelected && isSubmitted && !opt.isCorrect ? 'border-error bg-error' :
                      isSelected && !isSubmitted ? 'border-primary bg-primary' : 
                      'border-border bg-bg-surface'
                    }`}>
                      {isSelected && (
                        <svg className="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          {isSubmitted && !opt.isCorrect ? (
                             <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M6 18L18 6M6 6l12 12" />
                          ) : (
                             <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>
                  {rightIcon && (
                    <div className="flex-shrink-0 pl-2">
                      {rightIcon}
                    </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">
                <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>
                <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>
            );
          })()}

          {/* Action Button */}
          <div className="sticky bottom-3 z-10 mt-10 flex rounded-2xl bg-bg-surface/90 p-1 backdrop-blur md:static md:bg-transparent md:p-0">
            {!isSubmitted ? (
              <button
                onClick={handleSubmit}
                disabled={currentSelections.length === 0}
                className="w-full py-3.5 rounded-xl bg-primary hover:bg-primary-hover text-white font-bold text-lg tracking-wide disabled:opacity-50 disabled:bg-primary/50 disabled:hover:bg-primary/50 disabled:cursor-not-allowed transition-all duration-200 shadow-sm"
              >
                Submit Answer
              </button>
            ) : currentIndex + 1 < order.length ? (
              <button
                onClick={handleNext}
                className="w-full py-3.5 rounded-xl bg-primary hover:bg-primary-hover text-white font-bold text-lg tracking-wide transition-all duration-200 cursor-pointer shadow-sm"
              >
                Next Question
              </button>
            ) : (
              <button
                onClick={handleFinish}
                className="w-full py-3.5 rounded-xl bg-success hover:bg-success/90 text-white font-bold text-lg tracking-wide transition-all duration-200 cursor-pointer shadow-sm"
              >
                Finish Quiz
              </button>
            )}
          </div>

        </div>
      </div>
    </div>
  );
}
