import { createFileRoute, Link } from "@tanstack/react-router";
import { queryOptions, useSuspenseQuery, useQueryClient } from "@tanstack/react-query";
import { useState, useMemo, useEffect } from "react";
import { useServerFn } from "@tanstack/react-start";
import { getCourseForStudent, updateProgress } from "@/lib/course.functions";
import { getStudentDashboard } from "@/lib/dashboard.functions";
import { DashboardLayout } from "@/components/DashboardLayout";
import { VideoEmbed } from "@/components/VideoEmbed";
import { CheckCircle2, Circle, ChevronLeft, ChevronRight, Download, Lock } from "lucide-react";
import { toast } from "sonner";

const COURSE_ID = "11111111-1111-1111-1111-111111111111";
const courseQ = queryOptions({ queryKey: ["course", COURSE_ID], queryFn: () => getCourseForStudent({ data: { courseId: COURSE_ID } }) });
const dashQ = queryOptions({ queryKey: ["dashboard"], queryFn: () => getStudentDashboard() });

export const Route = createFileRoute("/_authenticated/learn")({
  loader: ({ context }) => Promise.all([context.queryClient.ensureQueryData(courseQ), context.queryClient.ensureQueryData(dashQ)]),
  component: LearnPage,
  errorComponent: ({ error }) => <div className="p-8 text-center text-destructive">{error.message}</div>,
});

function LearnPage() {
  const { data } = useSuspenseQuery(courseQ);
  const { data: dash } = useSuspenseQuery(dashQ);
  const qc = useQueryClient();
  const updateFn = useServerFn(updateProgress);

  const { course, isEnrolled, modules, lessons, progress, lastWatched, resources } = data;

  const orderedLessons = useMemo(() => {
    const out: typeof lessons = [];
    for (const m of modules) {
      const ml = lessons.filter((l) => l.module_id === m.id).sort((a, b) => a.position - b.position);
      out.push(...ml);
    }
    return out;
  }, [modules, lessons]);

  const initialId = lastWatched?.lesson_id ?? orderedLessons[0]?.id ?? null;
  const [currentId, setCurrentId] = useState<string | null>(initialId);
  const current = orderedLessons.find((l) => l.id === currentId) ?? orderedLessons[0];
  const idx = orderedLessons.findIndex((l) => l.id === current?.id);
  const completedSet = new Set(progress.filter((p) => p.completed).map((p) => p.lesson_id));

  useEffect(() => {
    // Save last-watched on selection (only if enrolled and has access)
    if (!current || !isEnrolled || !current.video_url) return;
    updateFn({ data: { courseId: COURSE_ID, lessonId: current.id, completed: completedSet.has(current.id) } }).catch(() => {});
    // intentionally only react to currentId
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentId]);

  if (!course) return null;
  if (!isEnrolled) {
    return (
      <DashboardLayout isAdmin={dash.isAdmin}>
        <div className="grid place-items-center rounded-2xl border border-dashed border-border bg-card p-12 text-center">
          <Lock className="h-10 w-10 text-warning" />
          <h2 className="mt-3 font-display text-2xl font-bold">Course Locked</h2>
          <p className="mt-2 max-w-md text-sm text-muted-foreground">
            You haven't been enrolled in this course yet. If you've submitted a payment, please wait for admin approval.
          </p>
          <Link to="/buy" className="mt-5 rounded-lg bg-gradient-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground">Enroll Now</Link>
        </div>
      </DashboardLayout>
    );
  }

  const markComplete = async () => {
    if (!current) return;
    try {
      await updateFn({ data: { courseId: COURSE_ID, lessonId: current.id, completed: true } });
      await qc.invalidateQueries({ queryKey: ["course", COURSE_ID] });
      await qc.invalidateQueries({ queryKey: ["dashboard"] });
      toast.success("Lesson marked complete");
      const next = orderedLessons[idx + 1];
      if (next) setCurrentId(next.id);
    } catch (e: any) { toast.error(e.message); }
  };

  return (
    <DashboardLayout isAdmin={dash.isAdmin}>
      <div className="mb-6 flex items-center justify-between">
        <div>
          <Link to="/dashboard" className="text-xs text-muted-foreground hover:text-foreground">← Dashboard</Link>
          <h1 className="mt-1 font-display text-2xl font-bold md:text-3xl">{course.title}</h1>
        </div>
      </div>

      <div className="grid gap-6 lg:grid-cols-[1fr_320px]">
        <div className="min-w-0">
          {current ? (
            <>
              <VideoEmbed url={current.video_url} poster={course.thumbnail_url ?? undefined} />
              <div className="mt-4">
                <h2 className="font-display text-xl font-semibold">{current.title}</h2>
                {current.description && <p className="mt-2 text-sm text-muted-foreground">{current.description}</p>}
              </div>

              <div className="mt-5 flex flex-wrap gap-2">
                <button disabled={idx <= 0} onClick={() => setCurrentId(orderedLessons[idx - 1].id)} className="inline-flex items-center gap-1 rounded-lg border border-border bg-card px-4 py-2 text-sm hover:bg-muted disabled:opacity-40">
                  <ChevronLeft className="h-4 w-4" /> Previous
                </button>
                <button onClick={markComplete} className="inline-flex items-center gap-1 rounded-lg bg-success px-4 py-2 text-sm font-semibold text-success-foreground">
                  <CheckCircle2 className="h-4 w-4" /> Mark Complete
                </button>
                <button disabled={idx >= orderedLessons.length - 1} onClick={() => setCurrentId(orderedLessons[idx + 1].id)} className="inline-flex items-center gap-1 rounded-lg bg-gradient-primary px-4 py-2 text-sm font-semibold text-primary-foreground disabled:opacity-40">
                  Next <ChevronRight className="h-4 w-4" />
                </button>
              </div>

              {resources.length > 0 && (
                <div className="mt-8">
                  <h3 className="font-display font-semibold">Resources</h3>
                  <ul className="mt-3 space-y-2">
                    {resources.map((r) => (
                      <li key={r.id}>
                        <a href={r.file_url} target="_blank" rel="noreferrer" className="flex items-center gap-2 rounded-lg border border-border bg-card px-4 py-3 text-sm hover:bg-muted">
                          <Download className="h-4 w-4 text-primary" /> {r.title}
                        </a>
                      </li>
                    ))}
                  </ul>
                </div>
              )}
            </>
          ) : <div>No lessons available.</div>}
        </div>

        {/* Lesson list */}
        <aside className="rounded-2xl border border-border bg-card p-4 lg:max-h-[calc(100vh-160px)] lg:overflow-y-auto scrollbar-thin">
          <h3 className="px-2 font-semibold">Course Content</h3>
          <div className="mt-3 space-y-4">
            {modules.map((m) => (
              <div key={m.id}>
                <p className="px-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">{m.title}</p>
                <ul className="mt-2 space-y-1">
                  {lessons.filter((l) => l.module_id === m.id).map((l) => {
                    const active = l.id === current?.id;
                    const done = completedSet.has(l.id);
                    return (
                      <li key={l.id}>
                        <button onClick={() => setCurrentId(l.id)} className={`flex w-full items-start gap-2 rounded-lg px-2 py-2 text-left text-sm transition ${active ? "bg-primary/15 text-primary" : "hover:bg-muted"}`}>
                          {done ? <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-success" /> : <Circle className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" />}
                          <span className="min-w-0 flex-1 truncate">{l.title}</span>
                          <span className="text-xs text-muted-foreground">{Math.round(l.duration_seconds / 60)}m</span>
                        </button>
                      </li>
                    );
                  })}
                </ul>
              </div>
            ))}
          </div>
        </aside>
      </div>
    </DashboardLayout>
  );
}
