"use client";

import { useState } from "react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Header } from "@/components/layout/header";
import { Footer } from "@/components/layout/footer";
import { PracticeSection } from "@/components/practice/practice-section";
import { useCollapsibleSidebar, SidebarBackdrop, SidebarToggle, sidebarAsideClass, sidebarNavClass } from "@/components/layout/collapsible-sidebar";
import { curriculum, type Unit, type Topic } from "@/lib/curriculum";
import { cn } from "@/lib/utils";
import type { Difficulty, MathProblem } from "@/lib/problems/types";

import { generateFractionAddSubtract, generateFractionMultiply, generateFractionDivide, generateFractionOfQuantity, generateWholeFromFraction, generateFractionBodmas, generateSignedFraction } from "@/lib/problems/generators/fraction-problems";
import { generateDecimalCompareOrder, generateDecimalRounding, generateStandardForm, generateDecimalAddSubtract, generateDecimalMultiplyDivide, generateDecimalConversion } from "@/lib/problems/generators/decimal-problems";
import { generateSimplifyRatio, generateDivideInRatio, generateRatioWordProblem, generateDefineRatio, generateFractionsAndRatios } from "@/lib/problems/generators/ratio-problems";
import { generateIntegerAddSubtractMixed, generateIntegerMultiplyDivide, generateIntegerOrderCompare } from "@/lib/problems/generators/integer-problems";
import { generateDigitValue, generateBinaryToDenary, generateQuaternaryToDenary } from "@/lib/problems/generators/number-system-problems";
import { generateIdentityInverse, generateExponentEvaluate, generateDistributive } from "@/lib/problems/generators/number-properties-problems";

type UnitColor = Unit["color"];
type PracticeUnitColor = Exclude<UnitColor, "unit-7">;
type Generator = (difficulty: Difficulty) => MathProblem;

/**
 * Practice for each curriculum topic. "lesson-only" topics (the coordinate grid)
 * need the interactive visual, so they link to their lesson instead of a
 * fill-in-the-answer generator. Keyed by `${unitSlug}/${topicSlug}`.
 */
const PRACTICE_BY_TOPIC: Record<string, Generator | "lesson-only"> = {
  "unit-1-fractions/add-subtract": generateFractionAddSubtract,
  "unit-1-fractions/multiply": generateFractionMultiply,
  "unit-1-fractions/divide": generateFractionDivide,
  "unit-1-fractions/mixed-operations": generateFractionBodmas,
  "unit-1-fractions/fraction-of-quantity": generateFractionOfQuantity,
  "unit-1-fractions/whole-from-fractions": generateWholeFromFraction,
  "unit-2-decimals/compare-order": generateDecimalCompareOrder,
  "unit-2-decimals/approximate": generateDecimalRounding,
  "unit-2-decimals/standard-form": generateStandardForm,
  "unit-3-decimal-operations/convert": generateDecimalConversion,
  "unit-3-decimal-operations/add-subtract": generateDecimalAddSubtract,
  "unit-3-decimal-operations/multiply-divide": generateDecimalMultiplyDivide,
  "unit-4-ratio-proportion/define-ratio": generateDefineRatio,
  "unit-4-ratio-proportion/fractions-and-ratios": generateFractionsAndRatios,
  "unit-4-ratio-proportion/simplify-ratios": generateSimplifyRatio,
  "unit-4-ratio-proportion/divide-in-ratio": generateDivideInRatio,
  "unit-4-ratio-proportion/word-problems": generateRatioWordProblem,
  "unit-5-integers/order-compare": generateIntegerOrderCompare,
  "unit-5-integers/add-subtract": generateIntegerAddSubtractMixed,
  "unit-5-integers/multiply-divide": generateIntegerMultiplyDivide,
  "unit-5-integers/negative-fractions": generateSignedFraction,
  "unit-6-number-system/place-value": generateDigitValue,
  "unit-6-number-system/binary": generateBinaryToDenary,
  "unit-6-number-system/quaternary": generateQuaternaryToDenary,
  "unit-7-coordinates/plot-points": "lesson-only",
  "unit-7-coordinates/read-coordinates": "lesson-only",
  "unit-8-number-properties/identity-inverse": generateIdentityInverse,
  "unit-8-number-properties/number-laws": generateDistributive,
  "unit-8-number-properties/exponents": generateExponentEvaluate,
};

function practiceFor(unit: Unit, topic: Topic): Generator | "lesson-only" {
  return PRACTICE_BY_TOPIC[`${unit.slug}/${topic.slug}`] ?? "lesson-only";
}

interface UnitStyle {
  heading: string;
  dot: string;
  accent: string;
  iconBg: string;
  hover: string;
  activeItem: string;
  headingHover: string;
}

const UNIT_STYLE: Record<UnitColor, UnitStyle> = {
  "unit-1": { heading: "text-unit-1-dark", dot: "bg-unit-1", accent: "border-l-unit-1", iconBg: "bg-unit-1-light text-unit-1-dark", hover: "hover:border-unit-1/40", activeItem: "bg-unit-1-light text-unit-1-dark border-unit-1/20", headingHover: "hover:bg-unit-1-light/50" },
  "unit-2": { heading: "text-unit-2-dark", dot: "bg-unit-2", accent: "border-l-unit-2", iconBg: "bg-unit-2-light text-unit-2-dark", hover: "hover:border-unit-2/40", activeItem: "bg-unit-2-light text-unit-2-dark border-unit-2/20", headingHover: "hover:bg-unit-2-light/50" },
  "unit-3": { heading: "text-unit-3-dark", dot: "bg-unit-3", accent: "border-l-unit-3", iconBg: "bg-unit-3-light text-unit-3-dark", hover: "hover:border-unit-3/40", activeItem: "bg-unit-3-light text-unit-3-dark border-unit-3/20", headingHover: "hover:bg-unit-3-light/50" },
  "unit-4": { heading: "text-unit-4-dark", dot: "bg-unit-4", accent: "border-l-unit-4", iconBg: "bg-unit-4-light text-unit-4-dark", hover: "hover:border-unit-4/40", activeItem: "bg-unit-4-light text-unit-4-dark border-unit-4/20", headingHover: "hover:bg-unit-4-light/50" },
  "unit-5": { heading: "text-unit-5-dark", dot: "bg-unit-5", accent: "border-l-unit-5", iconBg: "bg-unit-5-light text-unit-5-dark", hover: "hover:border-unit-5/40", activeItem: "bg-unit-5-light text-unit-5-dark border-unit-5/20", headingHover: "hover:bg-unit-5-light/50" },
  "unit-6": { heading: "text-unit-6-dark", dot: "bg-unit-6", accent: "border-l-unit-6", iconBg: "bg-unit-6-light text-unit-6-dark", hover: "hover:border-unit-6/40", activeItem: "bg-unit-6-light text-unit-6-dark border-unit-6/20", headingHover: "hover:bg-unit-6-light/50" },
  "unit-7": { heading: "text-unit-7-dark", dot: "bg-unit-7", accent: "border-l-unit-7", iconBg: "bg-unit-7-light text-unit-7-dark", hover: "hover:border-unit-7/40", activeItem: "bg-unit-7-light text-unit-7-dark border-unit-7/20", headingHover: "hover:bg-unit-7-light/50" },
  "unit-8": { heading: "text-unit-8-dark", dot: "bg-unit-8", accent: "border-l-unit-8", iconBg: "bg-unit-8-light text-unit-8-dark", hover: "hover:border-unit-8/40", activeItem: "bg-unit-8-light text-unit-8-dark border-unit-8/20", headingHover: "hover:bg-unit-8-light/50" },
};

interface Selection {
  unit: Unit;
  topic: Topic;
}

function PlayIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" fill="currentColor" className={className} aria-hidden="true">
      <path d="M8 5v14l11-7z" />
    </svg>
  );
}

// ── Sidebar (mirrors the lessons sidebar) ────────────────────────────────────

function PracticeSidebar({
  selected,
  onSelect,
  onAllTopics,
  mobileOpen,
  desktopCollapsed,
}: {
  selected: Selection | null;
  onSelect: (s: Selection) => void;
  onAllTopics: () => void;
  mobileOpen: boolean;
  desktopCollapsed: boolean;
}) {
  const [open, setOpen] = useState<Set<number>>(() => new Set([curriculum[0].number]));

  function toggle(num: number) {
    setOpen((prev) => {
      const next = new Set(prev);
      if (next.has(num)) next.delete(num);
      else next.add(num);
      return next;
    });
  }

  return (
    <aside className={sidebarAsideClass(mobileOpen, desktopCollapsed)}>
      <nav className={sidebarNavClass}>
        <button
          onClick={onAllTopics}
          className={cn(
            "mb-4 flex w-full items-center gap-2 rounded-xl px-3 py-2 text-sm font-medium transition-all duration-200",
            selected === null
              ? "bg-foreground text-background shadow-[var(--shadow-sm)]"
              : "text-muted hover:bg-background hover:text-foreground",
          )}
        >
          All Topics
        </button>

        <div className="mb-3 h-px bg-border/60" />

        {curriculum.map((unit) => {
          const style = UNIT_STYLE[unit.color];
          const isOpen = open.has(unit.number);
          return (
            <div key={unit.slug} className="mb-1">
              <button
                onClick={() => toggle(unit.number)}
                className={cn(
                  "flex w-full items-center justify-between rounded-xl px-3 py-2 text-left text-sm font-semibold transition-all duration-200",
                  style.heading,
                  style.headingHover,
                )}
              >
                <span className="truncate">Unit {unit.number}: {unit.title}</span>
                <svg
                  className={cn("h-4 w-4 shrink-0 transition-transform duration-200", isOpen && "rotate-90")}
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2}
                >
                  <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
                </svg>
              </button>

              {isOpen && (
                <div className="ml-2 mt-0.5 space-y-0.5 border-l-2 border-border/40 pl-2">
                  {unit.topics.map((topic) => {
                    const isActive = selected?.unit.slug === unit.slug && selected?.topic.slug === topic.slug;
                    return (
                      <button
                        key={topic.slug}
                        onClick={() => onSelect({ unit, topic })}
                        className={cn(
                          "flex w-full items-center gap-2 rounded-lg px-2.5 py-1.5 text-left text-sm transition-all duration-200",
                          isActive
                            ? cn(style.activeItem, "font-medium shadow-[var(--shadow-sm)]")
                            : "text-muted hover:text-foreground",
                        )}
                      >
                        <span className={cn("h-1.5 w-1.5 shrink-0 rounded-full transition-colors", isActive ? style.dot : "bg-border")} />
                        <span className="truncate">{topic.shortTitle}</span>
                      </button>
                    );
                  })}
                </div>
              )}
            </div>
          );
        })}
      </nav>
    </aside>
  );
}

// ── Topic browser (main area, all topics) ────────────────────────────────────

function TopicBrowser({ onSelect }: { onSelect: (s: Selection) => void }) {
  return (
    <div className="space-y-9">
      {curriculum.map((unit) => {
        const style = UNIT_STYLE[unit.color];
        return (
          <section key={unit.slug}>
            <div className="mb-3 flex items-center gap-2.5">
              <span className={cn("h-3.5 w-3.5 rounded-full", style.dot)} />
              <h2 className={cn("text-sm font-extrabold uppercase tracking-wider", style.heading)}>
                Unit {unit.number}: {unit.title}
              </h2>
              <span className="rounded-full bg-border/50 px-2 py-0.5 text-[0.7rem] font-bold text-muted">
                {unit.topics.length}
              </span>
            </div>

            <div className="grid gap-3 sm:grid-cols-2">
              {unit.topics.map((topic) => (
                <button
                  key={topic.slug}
                  onClick={() => onSelect({ unit, topic })}
                  className={cn(
                    "group flex items-center gap-3 rounded-2xl border-2 border-l-4 border-border/60 bg-surface p-4 text-left shadow-[var(--shadow-sm)] transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[var(--shadow-md)]",
                    style.accent,
                    style.hover,
                  )}
                >
                  <span className={cn("flex h-9 w-9 shrink-0 items-center justify-center rounded-xl", style.iconBg)}>
                    <PlayIcon className="h-4 w-4" />
                  </span>
                  <span className="flex-1 font-bold leading-tight">{topic.title}</span>
                  <svg
                    className="h-4 w-4 shrink-0 text-muted/40 transition-all duration-200 group-hover:translate-x-0.5 group-hover:text-muted"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke="currentColor"
                    strokeWidth={2.5}
                  >
                    <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
                  </svg>
                </button>
              ))}
            </div>
          </section>
        );
      })}
    </div>
  );
}

// ── Panel for topics that are practised in the interactive lesson ────────────

function LessonOnlyPanel({ unit, topic }: { unit: Unit; topic: Topic }) {
  return (
    <div className="rounded-3xl border-2 border-border/60 bg-surface p-8 text-center shadow-[var(--shadow-sm)]">
      <div className={cn("mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-2xl", UNIT_STYLE[unit.color].iconBg)}>
        <PlayIcon className="h-5 w-5" />
      </div>
      <h2 className="mb-2 text-xl font-bold">{topic.title}</h2>
      <p className="mx-auto mb-6 max-w-md text-sm text-muted">
        This topic uses the interactive coordinate grid, so it&apos;s best practised right in the lesson.
      </p>
      <Link href={`/lessons/${unit.slug}/${topic.slug}`}>
        <Button variant="primary" size="md">Open the interactive lesson →</Button>
      </Link>
    </div>
  );
}

// ── Page ─────────────────────────────────────────────────────────────────────

export default function PracticePage() {
  const [selected, setSelected] = useState<Selection | null>(null);
  const { mobileOpen, desktopCollapsed, toggle, closeMobile } = useCollapsibleSidebar();

  function select(s: Selection) {
    setSelected(s);
    closeMobile();
  }

  const generator = selected ? practiceFor(selected.unit, selected.topic) : null;

  return (
    <div className="playground-bg flex min-h-screen flex-col">
      <Header />
      <div className="playground-frame relative mx-auto flex w-full max-w-7xl flex-1">
        <SidebarBackdrop show={mobileOpen} onClick={closeMobile} />

        <PracticeSidebar
          selected={selected}
          onSelect={select}
          onAllTopics={() => {
            setSelected(null);
            closeMobile();
          }}
          mobileOpen={mobileOpen}
          desktopCollapsed={desktopCollapsed}
        />

        <main className="min-w-0 flex-1 bg-white">
          <div className="mx-auto max-w-4xl px-4 py-8 sm:px-6 lg:px-8">
            <SidebarToggle onClick={toggle} />

            {!selected ? (
              <>
                <h1 className="mb-2 text-3xl font-extrabold tracking-tight">Practice</h1>
                <p className="mb-8 text-muted">
                  Pick a topic and build your confidence with fresh questions each round.
                </p>
                <TopicBrowser onSelect={select} />
              </>
            ) : (
              <>
                <Button variant="secondary" size="sm" onClick={() => setSelected(null)} className="mb-6">
                  <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
                  </svg>
                  All Topics
                </Button>

                {generator === "lesson-only" || generator === null ? (
                  <LessonOnlyPanel unit={selected.unit} topic={selected.topic} />
                ) : (
                  <PracticeSection
                    key={`${selected.unit.slug}/${selected.topic.slug}`}
                    title={`Practice: ${selected.topic.title}`}
                    generator={generator}
                    unitColor={selected.unit.color as PracticeUnitColor}
                  />
                )}
              </>
            )}
          </div>
        </main>
      </div>
      <Footer />
    </div>
  );
}
