import { createFileRoute, Link, notFound } from "@tanstack/react-router";
import { useMutation } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Award, BookOpen, CalendarDays, CheckCircle2, Clock, Lock, Sparkles } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";

import { PageShell, Reveal } from "@/components/page-shell";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { useAuth } from "@/hooks/useAuth";
import { usePlan } from "@/hooks/usePlan";
import { getCourseBySlug } from "@/lib/catalog.functions";
import { requestCoursePurchase } from "@/lib/plan.functions";
import { PAYMENT_METHODS, courseAccessLabel, formatKesAmount, isSponsoredCourse, requiresPro } from "@/lib/plans";

type Lesson = { title: string; body?: string; summary?: string };

export const Route = createFileRoute("/courses/$slug")({
  loader: async ({ params }) => {
    const course = await getCourseBySlug({ data: { slug: params.slug } });
    if (!course) throw notFound();
    return { course };
  },
  head: ({ loaderData }) => {
    if (!loaderData) {
      return {
        meta: [
          { title: "Course unavailable | UZIA Academy" },
          { name: "robots", content: "noindex" },
        ],
      };
    }
    const { title, summary } = loaderData.course;
    return {
      meta: [
        { title: `${title} | UZIA Academy` },
        { name: "description", content: summary },
        { property: "og:title", content: `${title} | UZIA Academy` },
        { property: "og:description", content: summary },
      ],
    };
  },
  notFoundComponent: CourseNotFound,
  errorComponent: CourseNotFound,
  component: CourseDetail,
});

function CourseNotFound() {
  return (
    <PageShell>
      <div className="mx-auto max-w-2xl px-4 py-24 text-center">
        <h1 className="text-3xl">We couldn't find that course</h1>
        <p className="mt-3 text-sm text-muted-foreground">
          It may have been renamed or removed from the catalogue.
        </p>
        <Button asChild className="mt-6 rounded-full">
          <Link to="/courses">Back to all courses</Link>
        </Button>
      </div>
    </PageShell>
  );
}

function CourseDetail() {
  const { course } = Route.useLoaderData();
  const { user } = useAuth();
  const { isPro, courseIds } = usePlan();
  const locked = requiresPro(course) && !isPro && !courseIds.includes(course.id);
  const lessons: Lesson[] = Array.isArray(course.lessons) ? (course.lessons as Lesson[]) : [];
  const outcomes: string[] = Array.isArray(course.learning_outcomes)
    ? (course.learning_outcomes as string[])
    : [];

  return (
    <PageShell>
      <div className="relative overflow-hidden bg-sunset text-primary-foreground">
        <div className="motif-chevron absolute inset-0 opacity-25" aria-hidden />
        <div className="relative mx-auto w-full max-w-4xl px-4 py-16">
          <div className="flex flex-wrap items-center gap-2">
            <Badge className="bg-white/15 text-primary-foreground">
              {course.group_code} · {course.group_name}
            </Badge>
            <Badge className="bg-gold text-gold-foreground">
              <Award className="mr-1 size-3" /> {course.credential_level}
            </Badge>
            <Badge variant="outline" className="border-white/40 text-primary-foreground">
              {course.domain_code}
            </Badge>
            {isSponsoredCourse(course) ? (
              <Badge className="bg-primary text-primary-foreground">
                <Sparkles className="mr-1 size-3" /> Fully sponsored
              </Badge>
            ) : null}
          </div>
          <h1 className="mt-5 text-4xl sm:text-5xl">{course.title}</h1>
          <p className="mt-5 max-w-2xl opacity-90">{course.summary}</p>
          <div className="mt-7 flex flex-wrap items-center gap-6 text-sm opacity-90">
            <span className="flex items-center gap-1.5">
              <CalendarDays className="size-4" /> {course.duration_weeks} weeks
            </span>
            <span className="flex items-center gap-1.5">
              <Clock className="size-4" /> {course.learning_hours} learning hours
            </span>
            <span className="flex items-center gap-1.5">
              <BookOpen className="size-4" /> {lessons.length} modules
            </span>
          </div>
          <p className="mt-7 font-display text-3xl font-extrabold text-gold">
            {courseAccessLabel(course)}
          </p>
          {locked ? (
            <p className="mt-6 inline-flex items-center rounded-full border border-primary-foreground/30 px-4 py-2 text-sm font-semibold">
              <Lock className="mr-2 size-4" /> Payment required before learning begins
            </p>
          ) : (
            <>
              <Button
                asChild
                size="lg"
                className="mt-6 rounded-full bg-gold text-gold-foreground shadow-warm hover:bg-gold/90"
              >
                <Link to="/learn/$slug" params={{ slug: course.slug }}>
                  Enrol and start learning
                </Link>
              </Button>
              <p className="mt-2 text-xs opacity-80">
                Sign in required to track progress and claim your certificate.
              </p>
            </>
          )}
        </div>
        <div className="motif-divider" />
      </div>

      <section className="mx-auto w-full max-w-4xl px-4 py-16">
        {locked ? (
          <EnrollmentChoices course={course} signedIn={Boolean(user)} />
        ) : null}
        <Reveal>
          <h2 className="text-2xl">About this programme</h2>
          <p className="mt-4 text-muted-foreground">{course.description}</p>
        </Reveal>

        {outcomes.length ? (
          <Reveal delay={0.08}>
            <h2 className="mt-14 text-2xl">What you'll be able to do</h2>
            <ul className="mt-5 grid gap-3 sm:grid-cols-2">
              {outcomes.map((o) => (
                <li key={o} className="flex gap-2.5 rounded-2xl border border-border bg-card p-4">
                  <CheckCircle2 className="mt-0.5 size-4 shrink-0 text-primary" />
                  <span className="text-sm text-muted-foreground">{o}</span>
                </li>
              ))}
            </ul>
          </Reveal>
        ) : null}

        <Reveal delay={0.12}>
          <h2 className="mt-14 text-2xl">Weekly modules</h2>
          <ol className="mt-5 space-y-3">
            {lessons.map((lesson, i) => (
              <li
                key={lesson.title}
                className="flex gap-4 rounded-2xl border border-border bg-card p-5"
              >
                <span className="grid size-9 shrink-0 place-items-center rounded-xl bg-ember font-display text-sm font-bold text-primary-foreground">
                  {i + 1}
                </span>
                <div>
                  <p className="font-semibold">{lesson.title}</p>
                  {!locked && (lesson.body ?? lesson.summary) ? (
                    <p className="mt-1 text-sm text-muted-foreground">
                      {lesson.body ?? lesson.summary}
                    </p>
                  ) : null}
                </div>
              </li>
            ))}
          </ol>
        </Reveal>

        <Reveal delay={0.16}>
          <div className="mt-14 rounded-3xl border border-border bg-surface p-8">
            <Award className="size-7 text-primary" />
            <h2 className="mt-4 text-xl">{course.certificate_type}</h2>
            <p className="mt-2 text-sm text-muted-foreground">
              Complete every weekly module to claim a {course.credential_level}-level UZIA
              certificate with a unique number that anyone can verify publicly.
            </p>
          </div>
        </Reveal>
      </section>
    </PageShell>
  );
}

function EnrollmentChoices({
  course,
  signedIn,
}: {
  course: { id: string; slug: string; title: string; price_kes: number };
  signedIn: boolean;
}) {
  const submit = useServerFn(requestCoursePurchase);
  const [showForm, setShowForm] = useState(false);
  const [method, setMethod] = useState(PAYMENT_METHODS[0]?.id ?? "mpesa");
  const [form, setForm] = useState({ payment_reference: "", contact_email: "", contact_phone: "", notes: "" });
  const activeMethod = PAYMENT_METHODS.find((item) => item.id === method) ?? PAYMENT_METHODS[0];
  const mutation = useMutation({
    mutationFn: () => submit({ data: { course_id: course.id, payment_method: method, ...form } }),
    onSuccess: () => {
      toast.success("Payment reference received. UZIA Support will confirm your course access shortly.");
      setShowForm(false);
      setForm({ payment_reference: "", contact_email: "", contact_phone: "", notes: "" });
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : "Could not submit payment"),
  });

  return (
    <div className="mb-14 border-y border-border py-8">
      <p className="text-xs font-semibold uppercase tracking-[0.2em] text-terracotta">Choose how to enrol</p>
      <h2 className="mt-2 text-2xl">Start this course or access the full catalogue</h2>
      <div className="mt-6 grid gap-4 sm:grid-cols-2">
        <div className="rounded-2xl border border-border bg-card p-5">
          <p className="font-semibold">Buy this course</p>
          <p className="mt-2 font-display text-3xl text-terracotta">{formatKesAmount(course.price_kes)}</p>
          <p className="mt-2 text-sm text-muted-foreground">One payment for permanent access to {course.title}.</p>
          {signedIn ? (
            <Button className="mt-5 rounded-full" onClick={() => setShowForm((value) => !value)}>Enrol in this course</Button>
          ) : (
            <Button asChild className="mt-5 rounded-full"><Link to="/auth" search={{ redirect: `/courses/${course.slug}` }}>Sign in to enrol</Link></Button>
          )}
        </div>
        <div className="rounded-2xl border border-primary/30 bg-surface p-5">
          <p className="font-semibold">Choose monthly Pro</p>
          <p className="mt-2 text-sm text-muted-foreground">Unlock every paid course plus the complete action plan while your plan is active.</p>
          <Button asChild variant="outline" className="mt-5 rounded-full"><Link to="/pricing">Compare monthly plans</Link></Button>
        </div>
      </div>

      {showForm && activeMethod ? (
        <form className="mt-6 max-w-2xl space-y-4 rounded-2xl border border-border bg-surface p-6" onSubmit={(event) => { event.preventDefault(); mutation.mutate(); }}>
          <div className="space-y-2">
            <Label>Payment method</Label>
            <Select value={method} onValueChange={setMethod}>
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>{PAYMENT_METHODS.map((item) => <SelectItem key={item.id} value={item.id}>{item.label}</SelectItem>)}</SelectContent>
            </Select>
            <p className="text-xs text-muted-foreground">{activeMethod.instructions}</p>
          </div>
          <div className="space-y-2"><Label htmlFor="course-ref">Payment reference</Label><Input id="course-ref" required maxLength={120} value={form.payment_reference} onChange={(event) => setForm({ ...form, payment_reference: event.target.value })} /></div>
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2"><Label htmlFor="course-email">Contact email</Label><Input id="course-email" type="email" value={form.contact_email} onChange={(event) => setForm({ ...form, contact_email: event.target.value })} /></div>
            <div className="space-y-2"><Label htmlFor="course-phone">Phone</Label><Input id="course-phone" value={form.contact_phone} onChange={(event) => setForm({ ...form, contact_phone: event.target.value })} /></div>
          </div>
          <div className="space-y-2"><Label htmlFor="course-notes">Notes</Label><Textarea id="course-notes" value={form.notes} onChange={(event) => setForm({ ...form, notes: event.target.value })} /></div>
          <Button type="submit" className="rounded-full" disabled={mutation.isPending}>{mutation.isPending ? "Sending…" : "Submit payment reference"}</Button>
        </form>
      ) : null}
    </div>
  );
}
