"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { useAuth } from "@/lib/AuthContext";
import { useRouter, useParams } from "next/navigation";
import {
  ChevronLeft,
  ChevronRight,
  Play,
  Pause,
  CheckCircle2,
  RotateCcw,
  Loader2,
} from "lucide-react";
import ErrorFeedback from "@/components/ErrorFeedback";

// ── Types ──

interface ModuleProgress {
  completed: boolean;
  score: number | null;
  listened: boolean;
}

interface Module {
  id: string;
  order: number;
  title: string;
  slug: string;
  keyTakeaway: string | null;
  duration: number;
  content: string | null;
  quizData: Record<string, unknown> | null;
  progress: ModuleProgress | null;
}

interface Course {
  id: string;
  slug: string;
  title: string;
  author: string;
  description: string;
  imageUrl: string | null;
  moduleCount: number;
  totalMinutes: number;
  difficulty: string;
  giteaPath: string;
}

interface Enrollment {
  id: string;
  purchaseType: string;
  completed: boolean;
  progress: number;
}

interface CourseData {
  course: Course;
  modules: Module[];
  enrollment: Enrollment | null;
}

interface QuizQuestion {
  question: string;
  options: string[];
  correctIndex: number;
}

interface QuizData {
  questions: QuizQuestion[];
}

// ── Helpers ──

function parseQuizData(raw: Record<string, unknown> | null): QuizData | null {
  if (!raw) return null;
  const q = raw as QuizData;
  if (!Array.isArray(q.questions) || q.questions.length === 0) return null;
  // Validate each question has required fields
  const valid = q.questions.every(
    (qq) =>
      typeof qq.question === "string" &&
      Array.isArray(qq.options) &&
      qq.options.length >= 2 &&
      typeof qq.correctIndex === "number"
  );
  return valid ? q : null;
}

// ── Component ──

export default function LessonReaderPage() {
  const { user, token, loading: authLoading } = useAuth();
  const router = useRouter();
  const params = useParams();

  const slug = params.slug as string;
  const moduleId = params.moduleId as string; // This is the module slug

  const [data, setData] = useState<CourseData | null>(null);
  const [loadingData, setLoadingData] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Audio state
  const [isPlaying, setIsPlaying] = useState(false);
  const [audioLoading, setAudioLoading] = useState(false);
  const [audioError, setAudioError] = useState<string | null>(null);
  const synthRef = useRef<SpeechSynthesisUtterance | null>(null);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  // Quiz state
  const [quizAnswers, setQuizAnswers] = useState<Record<number, number>>({});
  const [quizSubmitted, setQuizSubmitted] = useState(false);
  const [quizScore, setQuizScore] = useState<number | null>(null);

  // Mark complete state
  const [completing, setCompleting] = useState(false);
  const [completed, setCompleted] = useState(false);

  // Listen query param detection (avoid useSearchParams for simplicity)
  const [listenParam, setListenParam] = useState(false);
  const [autoStarted, setAutoStarted] = useState(false);

  // Current module and navigation
  const currentModule = data?.modules.find((m) => m.slug === moduleId) ?? null;
  const moduleIndex =
    data?.modules.findIndex((m) => m.slug === moduleId) ?? -1;
  const prevModule =
    moduleIndex > 0 ? data?.modules[moduleIndex - 1] : null;
  const nextModule =
    moduleIndex < (data?.modules.length ?? 1) - 1
      ? data?.modules[moduleIndex + 1]
      : null;

  // Parsed quiz data
  const quizData = parseQuizData(currentModule?.quizData ?? null);

  // ── Fetch ──

  const fetchCourse = useCallback(async () => {
    if (!token) return;
    setLoadingData(true);
    setError(null);
    try {
      const res = await fetch(`/mobile/api/learn/courses/${slug}`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      if (res.ok) {
        const d: CourseData = await res.json();
        setData(d);
      } else {
        const d = await res.json().catch(() => ({}));
        setError(d.error || "Failed to load course");
      }
    } catch {
      setError("Network error. Please try again.");
    } finally {
      setLoadingData(false);
    }
  }, [token, slug]);

  // ── Auth guard ──

  useEffect(() => {
    if (!authLoading && !token) {
      router.push("/auth");
    }
  }, [authLoading, token, router]);

  // ── Fetch on mount ──

  useEffect(() => {
    if (token && slug) {
      fetchCourse();
    }
  }, [token, slug, fetchCourse]);

  // ── Detect listen query param ──

  useEffect(() => {
    if (typeof window !== "undefined") {
      const sp = new URLSearchParams(window.location.search);
      if (sp.get("listen") === "true") {
        setListenParam(true);
      }
    }
  }, []);

  // ── Set completed / score from server data ──

  useEffect(() => {
    if (!currentModule) return;
    if (currentModule.progress?.completed) {
      setCompleted(true);
    }
    if (
      currentModule.progress?.score !== null &&
      currentModule.progress?.score !== undefined
    ) {
      setQuizSubmitted(true);
      setQuizScore(currentModule.progress.score);
    }
  }, [currentModule]);

  // ── Auto-start audio when listen=true param AND data loaded ──

  useEffect(() => {
    if (listenParam && currentModule && !autoStarted && !audioLoading && !isPlaying) {
      setAutoStarted(true);
      // Small delay to let the render settle
      const t = setTimeout(() => handleListen(), 300);
      return () => clearTimeout(t);
    }
  }, [listenParam, currentModule, autoStarted]);

  // ── Cleanup on unmount ──

  useEffect(() => {
    return () => {
      window.speechSynthesis?.cancel();
      if (audioRef.current) {
        audioRef.current.pause();
        audioRef.current = null;
      }
    };
  }, []);

  // ── Audio handlers ──

  const useSpeechSynthesis = useCallback(() => {
    if (!currentModule?.content) {
      setAudioError("No content to read aloud.");
      return;
    }

    if (typeof window === "undefined" || !window.speechSynthesis) {
      setAudioError("Speech synthesis is not supported in this browser.");
      return;
    }

    window.speechSynthesis.cancel();

    const utterance = new SpeechSynthesisUtterance(currentModule.content);
    utterance.lang = "en-US";
    utterance.rate = 0.9;
    utterance.pitch = 1;

    utterance.onstart = () => setIsPlaying(true);
    utterance.onend = () => setIsPlaying(false);
    utterance.onerror = (e) => {
      console.error("SpeechSynthesis error:", e);
      setIsPlaying(false);
      setAudioError("Failed to play audio via speech synthesis.");
    };

    synthRef.current = utterance;
    window.speechSynthesis.speak(utterance);
  }, [currentModule]);

  const handleListen = useCallback(async () => {
    if (!currentModule) return;

    // Stop any current playback
    stopAudio();

    setAudioLoading(true);
    setAudioError(null);

    try {
      const res = await fetch(
        `/mobile/api/learn/tts?moduleId=${currentModule.id}`,
        {
          headers: { Authorization: `Bearer ${token}` },
        }
      );

      if (res.ok) {
        const ttsData = await res.json();
        if (ttsData.audioUrl) {
          // Server-provided audio URL
          const audio = new Audio(ttsData.audioUrl);
          audioRef.current = audio;
          audio.play().catch(() => {
            // Autoplay blocked — fallback to speech synthesis
            useSpeechSynthesis();
          });
          setIsPlaying(true);
          audio.onended = () => setIsPlaying(false);
          audio.onerror = () => {
            // Fallback on audio error
            useSpeechSynthesis();
          };
        } else {
          // No audio URL in response — use speech synthesis
          useSpeechSynthesis();
        }
      } else {
        // API error — fallback to speech synthesis
        useSpeechSynthesis();
      }
    } catch {
      // Network error — fallback to speech synthesis
      useSpeechSynthesis();
    } finally {
      setAudioLoading(false);
    }
  }, [currentModule, token, useSpeechSynthesis]);

  const stopAudio = useCallback(() => {
    if (synthRef.current) {
      window.speechSynthesis?.cancel();
      synthRef.current = null;
    }
    if (audioRef.current) {
      audioRef.current.pause();
      audioRef.current = null;
    }
    setIsPlaying(false);
  }, []);

  const togglePlayPause = useCallback(() => {
    if (isPlaying) {
      stopAudio();
    } else {
      handleListen();
    }
  }, [isPlaying, stopAudio, handleListen]);

  // ── Quiz handlers ──

  const handleQuizAnswer = (questionIndex: number, optionIndex: number) => {
    if (quizSubmitted) return;
    setQuizAnswers((prev) => ({ ...prev, [questionIndex]: optionIndex }));
  };

  const handleQuizSubmit = () => {
    if (!quizData) return;

    let correct = 0;
    quizData.questions.forEach((q, i) => {
      if (quizAnswers[i] === q.correctIndex) {
        correct++;
      }
    });

    const score = Math.round((correct / quizData.questions.length) * 100);
    setQuizScore(score);
    setQuizSubmitted(true);
  };

  // ── Mark Complete handler ──

  const handleMarkComplete = async () => {
    if (!currentModule || completing || completed) return;

    setCompleting(true);
    try {
      const res = await fetch("/mobile/api/learn/progress", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({
          moduleId: currentModule.id,
          completed: true,
        }),
      });

      if (res.ok) {
        setCompleted(true);
      } else {
        const d = await res.json().catch(() => ({}));
        setError(d.error || "Failed to update progress");
      }
    } catch {
      setError("Network error. Please try again.");
    } finally {
      setCompleting(false);
    }
  };

  // ── Loading screen (auth) ──

  if (authLoading) {
    return (
      <div className="min-h-dvh bg-[#0a0a0f] flex items-center justify-center">
        <div className="w-8 h-8 rounded-full border-2 border-[#D4AF37]/30 border-t-[#D4AF37] animate-spin" />
      </div>
    );
  }

  if (!user) return null;

  // ── Loading screen (data) ──

  if (loadingData) {
    return (
      <div className="min-h-dvh bg-[#0a0a0f]">
        <div className="sticky top-0 z-20 bg-[#0a0a0f]/90 backdrop-blur-lg border-b border-gray-800/40">
          <div className="flex items-center gap-3 px-4 h-12">
            <button
              onClick={() => router.push(`/learn/${slug}`)}
              className="w-8 h-8 rounded-full bg-gray-800/60 flex items-center justify-center active:bg-gray-700/60 transition"
            >
              <ChevronLeft size={16} className="text-gray-400" />
            </button>
            <div className="h-4 bg-gray-800/40 rounded w-40 animate-pulse" />
          </div>
        </div>
        <div className="flex flex-col items-center justify-center py-20">
          <Loader2 size={32} className="text-[#D4AF37] animate-spin mb-3" />
          <p className="text-sm text-gray-500">Loading lesson...</p>
        </div>
      </div>
    );
  }

  // ── Error state ──

  if (error) {
    return (
      <div className="min-h-dvh bg-[#0a0a0f]">
        <div className="sticky top-0 z-20 bg-[#0a0a0f]/90 backdrop-blur-lg border-b border-gray-800/40">
          <div className="flex items-center gap-3 px-4 h-12">
            <button
              onClick={() => router.push(`/learn/${slug}`)}
              className="w-8 h-8 rounded-full bg-gray-800/60 flex items-center justify-center active:bg-gray-700/60 transition"
            >
              <ChevronLeft size={16} className="text-gray-400" />
            </button>
          </div>
        </div>
        <ErrorFeedback
          error={error}
          kind="network"
          onRetry={fetchCourse}
          context="lesson reader"
        />
      </div>
    );
  }

  // ── Module not found ──

  if (!currentModule) {
    return (
      <div className="min-h-dvh bg-[#0a0a0f]">
        <div className="sticky top-0 z-20 bg-[#0a0a0f]/90 backdrop-blur-lg border-b border-gray-800/40">
          <div className="flex items-center gap-3 px-4 h-12">
            <button
              onClick={() => router.push(`/learn/${slug}`)}
              className="w-8 h-8 rounded-full bg-gray-800/60 flex items-center justify-center active:bg-gray-700/60 transition"
            >
              <ChevronLeft size={16} className="text-gray-400" />
            </button>
          </div>
        </div>
        <div className="mx-4 mt-4 bg-gray-900/40 border border-gray-800/60 rounded-2xl p-6 text-center">
          <p className="text-sm text-gray-400">Module not found</p>
          <button
            onClick={() => router.push(`/learn/${slug}`)}
            className="mt-3 text-xs text-[#D4AF37] underline"
          >
            Back to course
          </button>
        </div>
      </div>
    );
  }

  // ── Render ──

  return (
    <div className="min-h-dvh bg-[#0a0a0f] pb-28">
      {/* ── Sticky header ── */}
      <div className="sticky top-0 z-20 bg-[#0a0a0f]/90 backdrop-blur-lg border-b border-gray-800/40">
        <div className="flex items-center gap-3 px-4 h-12">
          <button
            onClick={() => router.push(`/learn/${slug}`)}
            className="w-8 h-8 rounded-full bg-gray-800/60 flex items-center justify-center active:bg-gray-700/60 transition"
          >
            <ChevronLeft size={16} className="text-gray-400" />
          </button>
          <h1 className="text-sm font-semibold text-white truncate flex-1">
            {currentModule.title}
          </h1>
          {completed && (
            <CheckCircle2 size={16} className="text-emerald-400 shrink-0" />
          )}
        </div>
      </div>

      {/* ── Content ── */}
      <div className="px-4 pt-4 pb-6">
        {/* Module header */}
        <div className="mb-4">
          <span className="text-[10px] text-gray-600 font-medium uppercase tracking-wider">
            Module {currentModule.order}
          </span>
          <h2 className="text-lg font-bold text-white mt-1">
            {currentModule.title}
          </h2>
          {currentModule.keyTakeaway && (
            <p className="text-xs text-gray-500 mt-2 leading-relaxed italic border-l-2 border-[#D4AF37]/30 pl-3">
              {currentModule.keyTakeaway}
            </p>
          )}
        </div>

        {/* ── Listen button ── */}
        <div className="flex items-center gap-3 mb-5">
          <button
            onClick={togglePlayPause}
            disabled={audioLoading}
            className="flex items-center gap-2 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-3 active:bg-[#D4AF37]/25 transition disabled:opacity-60"
          >
            {audioLoading ? (
              <Loader2 size={16} className="text-[#D4AF37] animate-spin" />
            ) : isPlaying ? (
              <Pause size={16} className="text-[#D4AF37]" />
            ) : (
              <Play size={16} className="text-[#D4AF37]" />
            )}
            <span className="text-sm font-medium text-[#D4AF37]">
              {audioLoading
                ? "Loading..."
                : isPlaying
                  ? "Pause"
                  : "Listen 🎧"}
            </span>
          </button>
          {isPlaying && (
            <button
              onClick={stopAudio}
              className="flex items-center gap-1 bg-gray-800/60 border border-gray-700/40 rounded-xl px-3 py-3 active:bg-gray-700/60 transition"
            >
              <RotateCcw size={14} className="text-gray-400" />
              <span className="text-xs font-medium text-gray-400">Stop</span>
            </button>
          )}
        </div>

        {/* Audio error */}
        {audioError && (
          <div className="mb-4 bg-red-900/10 border border-red-800/30 rounded-xl p-3">
            <p className="text-xs text-red-400">{audioError}</p>
          </div>
        )}

        {/* ── Module content ── */}
        {currentModule.content ? (
          <div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-5 mb-6">
            <div className="text-gray-300 leading-relaxed whitespace-pre-wrap text-sm">
              {currentModule.content}
            </div>
          </div>
        ) : (
          <div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-6 mb-6 text-center">
            <p className="text-sm text-gray-500">
              No content available for this module.
            </p>
          </div>
        )}

        {/* ── Quiz section ── */}
        {quizData && (
          <div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-5 mb-6">
            <h3 className="text-sm font-bold text-white mb-4 flex items-center gap-2">
              <span className="w-6 h-6 rounded-lg bg-[#D4AF37]/15 flex items-center justify-center">
                <span className="text-xs text-[#D4AF37] font-bold">?</span>
              </span>
              Quiz
            </h3>

            {/* Score banner */}
            {quizSubmitted && quizScore !== null && (
              <div
                className={`mb-4 rounded-xl p-3 ${
                  quizScore >= 80
                    ? "bg-emerald-900/10 border border-emerald-800/30"
                    : quizScore >= 50
                      ? "bg-amber-900/10 border border-amber-800/30"
                      : "bg-red-900/10 border border-red-800/30"
                }`}
              >
                <p
                  className={`text-xs font-medium ${
                    quizScore >= 80
                      ? "text-emerald-300"
                      : quizScore >= 50
                        ? "text-amber-300"
                        : "text-red-300"
                  }`}
                >
                  Score: {quizScore}% (
                  {Math.round(
                    (quizScore * quizData.questions.length) / 100
                  )}
                  /{quizData.questions.length} correct)
                </p>
              </div>
            )}

            {/* Questions */}
            <div className="space-y-5">
              {quizData.questions.map((q, qIdx) => (
                <div key={qIdx}>
                  <p className="text-sm text-white font-medium mb-2">
                    {qIdx + 1}. {q.question}
                  </p>
                  <div className="space-y-1.5">
                    {q.options.map((opt, oIdx) => {
                      const isSelected = quizAnswers[qIdx] === oIdx;
                      const isCorrect =
                        quizSubmitted && oIdx === q.correctIndex;
                      const isWrong =
                        quizSubmitted && isSelected && oIdx !== q.correctIndex;

                      let optionStyle =
                        "bg-gray-800/40 border-gray-700/40 text-gray-400";
                      if (isSelected && !quizSubmitted) {
                        optionStyle =
                          "bg-[#D4AF37]/10 border-[#D4AF37]/40 text-[#D4AF37]";
                      }
                      if (quizSubmitted) {
                        if (isCorrect) {
                          optionStyle =
                            "bg-emerald-900/20 border-emerald-500/40 text-emerald-300";
                        } else if (isWrong) {
                          optionStyle =
                            "bg-red-900/20 border-red-500/40 text-red-300";
                        } else {
                          optionStyle =
                            "bg-gray-800/20 border-gray-700/30 text-gray-500";
                        }
                      }

                      return (
                        <button
                          key={oIdx}
                          onClick={() => handleQuizAnswer(qIdx, oIdx)}
                          disabled={quizSubmitted}
                          className={`w-full text-left rounded-xl px-3.5 py-2.5 text-xs border transition ${
                            quizSubmitted
                              ? "cursor-default"
                              : "active:scale-[0.98]"
                          } ${optionStyle}`}
                        >
                          <span className="inline-flex items-center justify-center w-5 h-5 rounded-full border border-current text-center text-[10px] mr-2 shrink-0">
                            {String.fromCharCode(65 + oIdx)}
                          </span>
                          {opt}
                          {quizSubmitted && isCorrect && (
                            <span className="float-right text-emerald-400">
                              ✓
                            </span>
                          )}
                          {quizSubmitted && isWrong && (
                            <span className="float-right text-red-400">
                              ✗
                            </span>
                          )}
                        </button>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>

            {/* Submit / Retry buttons */}
            {!quizSubmitted ? (
              <button
                onClick={handleQuizSubmit}
                disabled={
                  Object.keys(quizAnswers).length < quizData.questions.length
                }
                className="w-full mt-4 bg-[#D4AF37] text-[#0a0a0f] text-sm font-semibold rounded-xl px-4 py-3 active:bg-[#c5a233] transition disabled:opacity-40"
              >
                Submit Answers
              </button>
            ) : (
              <button
                onClick={() => {
                  setQuizAnswers({});
                  setQuizSubmitted(false);
                  setQuizScore(null);
                }}
                className="w-full mt-3 bg-gray-800/60 border border-gray-700/40 text-gray-300 text-sm font-medium rounded-xl px-4 py-3 active:bg-gray-700/60 transition"
              >
                Retry Quiz
              </button>
            )}
          </div>
        )}

        {/* ── Mark Complete button ── */}
        <button
          onClick={handleMarkComplete}
          disabled={completing || completed}
          className={`w-full flex items-center justify-center gap-2 rounded-xl px-4 py-3.5 text-sm font-semibold transition ${
            completed
              ? "bg-emerald-500/15 border border-emerald-500/30 text-emerald-400"
              : "bg-[#D4AF37] text-[#0a0a0f] active:bg-[#c5a233] disabled:opacity-40"
          }`}
        >
          {completing ? (
            <>
              <Loader2 size={16} className="animate-spin" />
              Saving...
            </>
          ) : completed ? (
            <>
              <CheckCircle2 size={16} />
              Completed ✓
            </>
          ) : (
            <>
              <CheckCircle2 size={16} />
              Mark Complete
            </>
          )}
        </button>

        {/* ── Previous / Next navigation ── */}
        {(prevModule || nextModule) && (
          <div className="flex items-center gap-3 mt-4">
            {prevModule ? (
              <button
                onClick={() =>
                  router.push(`/learn/${slug}/${prevModule.slug}`)
                }
                className="flex-1 flex items-center gap-2 bg-gray-800/60 border border-gray-700/40 rounded-xl px-4 py-3 active:bg-gray-700/60 transition min-w-0"
              >
                <ChevronLeft size={16} className="text-gray-400 shrink-0" />
                <div className="text-left flex-1 min-w-0">
                  <span className="text-[10px] text-gray-600 block">
                    Previous
                  </span>
                  <span className="text-xs text-gray-300 truncate block">
                    {prevModule.title}
                  </span>
                </div>
              </button>
            ) : (
              <div className="flex-1" />
            )}

            {nextModule ? (
              <button
                onClick={() =>
                  router.push(`/learn/${slug}/${nextModule.slug}`)
                }
                className="flex-1 flex items-center gap-2 bg-gray-800/60 border border-gray-700/40 rounded-xl px-4 py-3 active:bg-gray-700/60 transition min-w-0"
              >
                <div className="text-right flex-1 min-w-0">
                  <span className="text-[10px] text-gray-600 block">
                    Next
                  </span>
                  <span className="text-xs text-gray-300 truncate block">
                    {nextModule.title}
                  </span>
                </div>
                <ChevronRight size={16} className="text-gray-400 shrink-0" />
              </button>
            ) : (
              <div className="flex-1" />
            )}
          </div>
        )}
      </div>
    </div>
  );
}
