import { useCallback, useEffect, useState } from "react";
import {
  AlertCircle,
  ArrowLeft,
  BookOpen,
  Calendar,
  Clock,
  Hash,
  Loader2,
  RefreshCw,
  Sparkles,
} from "lucide-react";
import { Link, useNavigate, useParams, useSearchParams } from "react-router-dom";
import { toast } from "sonner";
import { getPracticesByParentLesson } from "../../api/courses.api";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import { Card, CardContent } from "../../components/ui/card";
import type {
  GetPracticesByParentContextResponse,
  ParentContextPractice,
} from "../../types/course.types";
import { resolveThumbnailForPreview } from "../../lib/videoPreview";
import { cn } from "../../lib/utils";

function unwrapPracticesEnvelope(
  res: { data?: GetPracticesByParentContextResponse & { Data?: GetPracticesByParentContextResponse["data"] } },
): GetPracticesByParentContextResponse["data"] | null {
  const b = res.data;
  if (!b) return null;
  return b.data ?? b.Data ?? null;
}

function formatPracticeDate(iso: string): string {
  const d = new Date(iso);
  return Number.isNaN(d.getTime())
    ? iso
    : d.toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" });
}

function PracticeCard({
  practice,
  index,
  total,
}: {
  practice: ParentContextPractice;
  index: number;
  total: number;
}) {
  const [imgFailed, setImgFailed] = useState(false);
  const thumb = resolveThumbnailForPreview(practice.story_image);
  const showThumb = Boolean(thumb) && !imgFailed;

  return (
    <Card
      className={cn(
        "overflow-hidden border-grayScale-100/90 bg-white shadow-sm transition-all duration-300",
        "hover:border-brand-200/60 hover:shadow-md hover:shadow-brand-500/5",
      )}
    >
      <CardContent className="p-0">
        <div className="flex flex-col lg:flex-row lg:items-stretch">
          <div className="relative shrink-0 lg:w-[280px]">
            <div
              className={cn(
                "relative aspect-[16/10] w-full overflow-hidden bg-gradient-to-br from-grayScale-100 to-grayScale-50 lg:aspect-auto lg:h-full lg:min-h-[220px]",
                !showThumb && "grid min-h-[180px] place-items-center lg:min-h-[220px]",
              )}
            >
              {showThumb ? (
                <>
                  <img
                    src={thumb!}
                    alt=""
                    className="h-full w-full object-cover"
                    onError={() => setImgFailed(true)}
                  />
                  <div className="pointer-events-none absolute inset-0 bg-gradient-to-t from-black/25 via-transparent to-black/10" />
                </>
              ) : (
                <div className="flex flex-col items-center gap-2 text-grayScale-400">
                  <div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-white/80 shadow-inner ring-1 ring-grayScale-200/80">
                    <BookOpen className="h-7 w-7" />
                  </div>
                  <span className="text-[11px] font-semibold uppercase tracking-wider">
                    No cover image
                  </span>
                </div>
              )}
            </div>
          </div>

          <div className="flex min-w-0 flex-1 flex-col p-6 sm:p-7">
            <div className="mb-3 flex flex-wrap items-center gap-2">
              <span className="text-[11px] font-bold uppercase tracking-[0.14em] text-brand-500">
                Practice {index + 1} of {total}
              </span>
              <Badge variant="secondary" className="font-mono text-[10px] font-semibold">
                ID {practice.id}
              </Badge>
            </div>

            <h2 className="text-xl font-semibold leading-snug tracking-tight text-grayScale-900 sm:text-[1.35rem]">
              {practice.title}
            </h2>

            {practice.story_description?.trim() ? (
              <div className="mt-4 rounded-xl border border-grayScale-100 bg-grayScale-50/80 px-4 py-3.5">
                <p className="text-[10px] font-bold uppercase tracking-wider text-grayScale-400">
                  Story & instructions
                </p>
                <p className="mt-2 whitespace-pre-line text-[14px] leading-relaxed text-grayScale-700">
                  {practice.story_description}
                </p>
              </div>
            ) : null}

            {practice.quick_tips?.trim() ? (
              <div className="mt-4 border-l-[3px] border-amber-400 bg-gradient-to-r from-amber-50/90 to-amber-50/30 py-3 pl-4 pr-3">
                <p className="text-[10px] font-bold uppercase tracking-wider text-amber-900/75">
                  Quick tips
                </p>
                <p className="mt-1.5 whitespace-pre-line text-[13px] leading-relaxed text-grayScale-800">
                  {practice.quick_tips}
                </p>
              </div>
            ) : null}

            <div className="mt-6 flex flex-wrap gap-2 border-t border-grayScale-100 pt-5">
              <Badge variant="secondary" className="gap-1.5 pl-2 pr-2.5 py-1 font-medium normal-case">
                <Hash className="h-3 w-3 opacity-70" aria-hidden />
                Question set {practice.question_set_id}
              </Badge>
              <Badge variant="secondary" className="gap-1.5 pl-2 pr-2.5 py-1 font-medium normal-case">
                <Clock className="h-3 w-3 opacity-70" aria-hidden />
                {formatPracticeDate(practice.created_at)}
              </Badge>
            </div>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

export function LessonPracticesPage() {
  const navigate = useNavigate();
  const { level, courseId, moduleId, lessonId } = useParams<{
    level: string;
    courseId: string;
    moduleId: string;
    lessonId: string;
  }>();
  const [searchParams] = useSearchParams();
  const lessonTitle = searchParams.get("lessonTitle")?.trim() || "";

  const backHref = `/new-content/learn-english/${level}/courses/${courseId}/modules/${moduleId}`;

  const [practices, setPractices] = useState<ParentContextPractice[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState<string | null>(null);

  const lid = lessonId ? Number(lessonId) : NaN;
  const validLesson = Number.isFinite(lid) && lid > 0;

  const load = useCallback(async () => {
    if (!validLesson) {
      setLoading(false);
      setLoadError("Invalid lesson.");
      setPractices([]);
      return;
    }
    setLoading(true);
    setLoadError(null);
    try {
      const res = await getPracticesByParentLesson(lid, { limit: 100, offset: 0 });
      const envelope = unwrapPracticesEnvelope(res);
      const list = Array.isArray(envelope?.practices) ? envelope.practices : [];
      setPractices(list);
      setTotalCount(
        typeof envelope?.total_count === "number"
          ? envelope.total_count
          : list.length,
      );
    } catch {
      setPractices([]);
      setTotalCount(0);
      setLoadError("Could not load practices for this lesson.");
      toast.error("Failed to load practices");
    } finally {
      setLoading(false);
    }
  }, [lid, validLesson]);

  useEffect(() => {
    void load();
  }, [load]);

  const displayTitle =
    lessonTitle || (validLesson ? `Lesson #${lid}` : "Lesson practices");

  const addPracticeHref = `/new-content/learn-english/${level}/courses/add-practice?backTo=module&courseId=${courseId}&moduleId=${moduleId}&lessonId=${lid}&lessonTitle=${encodeURIComponent(lessonTitle || displayTitle)}`;

  return (
    <div className="min-h-screen bg-gradient-to-b from-[#F4F6FB] via-white to-[#F8FAFC]">
      <div className="pointer-events-none fixed inset-0 -z-10 overflow-hidden">
        <div className="absolute -right-24 -top-24 h-72 w-72 rounded-full bg-brand-500/[0.06] blur-3xl" />
        <div className="absolute -bottom-32 -left-20 h-80 w-80 rounded-full bg-violet-500/[0.05] blur-3xl" />
      </div>

      <div className="mx-auto max-w-4xl px-4 pb-24 pt-8 sm:px-6 lg:px-8">
        <div className="animate-in fade-in slide-in-from-bottom-2 duration-500">
          <Link
            to={backHref}
            className="group mb-6 inline-flex items-center gap-2 rounded-full border border-transparent px-1 py-1 text-[14px] font-medium text-grayScale-600 transition-colors hover:border-grayScale-200 hover:bg-white/80 hover:text-brand-600"
          >
            <span className="flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-sm ring-1 ring-grayScale-100 transition-transform group-hover:-translate-x-0.5">
              <ArrowLeft className="h-4 w-4" />
            </span>
            Back to module
          </Link>

          <Card className="mb-10 border-grayScale-100/80 bg-white/90 shadow-md shadow-grayScale-200/40 backdrop-blur-sm">
            <CardContent className="p-6 sm:p-8">
              <div className="flex flex-col gap-6 lg:flex-row lg:items-start lg:justify-between">
                <div className="flex min-w-0 gap-4">
                  <div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-brand-500 to-brand-600 text-white shadow-lg shadow-brand-500/25">
                    <BookOpen className="h-7 w-7" strokeWidth={1.75} />
                  </div>
                  <div className="min-w-0">
                    <p className="text-[11px] font-bold uppercase tracking-[0.2em] text-brand-500/90">
                      Lesson practices
                    </p>
                    <h1 className="mt-1.5 text-2xl font-semibold tracking-tight text-grayScale-900 sm:text-3xl">
                      {displayTitle}
                    </h1>
                    <p className="mt-2 max-w-xl text-[15px] leading-relaxed text-grayScale-500">
                      Review speaking practices linked to this lesson. Thumbnails
                      and copy come from your published practice content.
                    </p>
                    {!loading && !loadError ? (
                      <div className="mt-4 flex flex-wrap items-center gap-2">
                        <Badge variant="default" className="px-3 py-1 text-xs font-semibold">
                          {practices.length}{" "}
                          {practices.length === 1 ? "practice" : "practices"}
                        </Badge>
                        {totalCount > practices.length ? (
                          <span className="text-[12px] text-grayScale-500">
                            Showing {practices.length} of {totalCount}
                          </span>
                        ) : null}
                      </div>
                    ) : null}
                  </div>
                </div>

                <div className="flex shrink-0 flex-col gap-2 sm:flex-row lg:flex-col">
                  <Button
                    type="button"
                    className="h-11 rounded-xl bg-brand-500 px-6 font-semibold shadow-md shadow-brand-500/20 hover:bg-brand-600"
                    onClick={() => void navigate(addPracticeHref)}
                  >
                    <Calendar className="mr-2 h-4 w-4" />
                    Add practice
                  </Button>
                  <Button
                    type="button"
                    variant="outline"
                    className="h-11 rounded-xl border-grayScale-200 font-semibold text-grayScale-700 hover:bg-grayScale-50"
                    disabled={loading}
                    onClick={() => void load()}
                  >
                    <RefreshCw
                      className={cn("mr-2 h-4 w-4", loading && "animate-spin")}
                    />
                    Refresh
                  </Button>
                </div>
              </div>
            </CardContent>
          </Card>

          {loading ? (
            <Card className="border-grayScale-100 bg-white/95 py-20 shadow-sm">
              <CardContent className="flex flex-col items-center justify-center gap-4 pt-6">
                <div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-brand-50 ring-1 ring-brand-100">
                  <Loader2 className="h-8 w-8 animate-spin text-brand-500" />
                </div>
                <div className="text-center">
                  <p className="text-[16px] font-semibold text-grayScale-800">
                    Loading practices
                  </p>
                  <p className="mt-1 text-[14px] text-grayScale-500">
                    Fetching content for this lesson…
                  </p>
                </div>
              </CardContent>
            </Card>
          ) : loadError ? (
            <Card className="border-red-100 bg-gradient-to-br from-red-50/90 to-white shadow-sm">
              <CardContent className="flex flex-col items-center gap-5 py-14 text-center sm:py-16">
                <div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-red-100 text-red-600">
                  <AlertCircle className="h-8 w-8" />
                </div>
                <div>
                  <p className="text-lg font-semibold text-grayScale-900">
                    Something went wrong
                  </p>
                  <p className="mx-auto mt-2 max-w-md text-[14px] leading-relaxed text-grayScale-600">
                    {loadError}
                  </p>
                </div>
                <Button
                  type="button"
                  variant="outline"
                  className="rounded-xl border-grayScale-300 font-semibold"
                  onClick={() => void load()}
                >
                  Try again
                </Button>
              </CardContent>
            </Card>
          ) : practices.length === 0 ? (
            <Card className="border-dashed border-grayScale-200 bg-white/90 shadow-sm">
              <CardContent className="flex flex-col items-center px-6 py-16 text-center sm:py-20">
                <div className="mb-6 flex h-20 w-20 items-center justify-center rounded-3xl bg-gradient-to-br from-violet-50 to-brand-50 ring-1 ring-brand-100/60">
                  <Sparkles className="h-9 w-9 text-brand-500" strokeWidth={1.5} />
                </div>
                <p className="text-xl font-semibold text-grayScale-900">
                  No practices yet
                </p>
                <p className="mx-auto mt-3 max-w-md text-[15px] leading-relaxed text-grayScale-500">
                  This lesson does not have any linked practices. Create one to
                  give learners a structured speaking activity after the video.
                </p>
                <div className="mt-8 flex flex-col gap-3 sm:flex-row">
                  <Button
                    type="button"
                    className="h-11 rounded-xl bg-brand-500 px-8 font-semibold shadow-md shadow-brand-500/15 hover:bg-brand-600"
                    onClick={() => void navigate(addPracticeHref)}
                  >
                    <Calendar className="mr-2 h-4 w-4" />
                    Create practice
                  </Button>
                  <Button
                    type="button"
                    variant="outline"
                    className="h-11 rounded-xl border-grayScale-200 px-8 font-semibold"
                    asChild
                  >
                    <Link to={backHref}>Return to module</Link>
                  </Button>
                </div>
              </CardContent>
            </Card>
          ) : (
            <div className="space-y-5">
              {practices.map((p, i) => (
                <PracticeCard
                  key={p.id}
                  practice={p}
                  index={i}
                  total={practices.length}
                />
              ))}
              <p className="px-1 text-center text-[11px] text-grayScale-400">
                Source:{" "}
                <code className="rounded-md bg-grayScale-100 px-1.5 py-0.5 font-mono text-[10px] text-grayScale-500">
                  GET /lessons/{lid}/practices
                </code>
              </p>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
