"use client";

import { type ChangeEvent, useEffect, useState } from "react";
import { Calendar, MarkerPin02, Star01 } from "@untitledui/icons";
import {
  Avatar,
  Badge,
  BadgeGroup,
  BadgeWithDot,
  Button,
  FeaturedIcon,
  Input,
  MarkdownRenderer,
  NativeSelect,
  PaginationPageDefault,
  PhotoWithFallback,
  RoundButton,
  Select,
  SelectItem,
  Textarea,
  VideoModal,
  VideoPlayButton,
} from "../../design_system/elements";
import {
  AboutHome,
  BlogGallery,
  BlogHome,
  BlogSection,
  BlogPostSection,
  ContactHome,
  ContactSection,
  FAQGrid,
  FAQHero,
  FAQHome,
  FooterHome,
  GenericHeaderComponent,
  GenericTextHero,
  HeaderNavigation,
  HeroHome,
  HomeHeroComponent,
  JobApplicationForm,
  JobDetailHero,
  JobDetailSection,
  JobGallery,
  LocationDetailHero,
  LocationDetailsSection,
  LocationGrid,
  PolicyDocumentSection,
  ServiceDetailHero,
  ServicesGrid,
  ServicesHome,
  SocialMediaGrid,
  SocialMediaHero,
  StatisticsSection,
  TeamGrid,
  TestimonialsHero,
  TestimonialsHome,
  TestimonialsGrid,
  ValuesSection,
} from "../../design_system/sections";
import type { Theme } from "../../themes";

const THEMES: { label: string; value: Theme }[] = [
  { label: "Classic", value: "classic" },
  { label: "Aman", value: "aman" },
  { label: "Barelux", value: "barelux" },
  { label: "Balance", value: "balance" },
];

export type GallerySection = "colors" | "fonts" | "elements" | "sections" | "pages";

const SIDEBAR_ITEMS: { id: GallerySection; label: string }[] = [
  { id: "colors", label: "Colors" },
  { id: "fonts", label: "Fonts" },
  { id: "elements", label: "Elements" },
  { id: "sections", label: "Sections" },
  { id: "pages", label: "Pages" },
];

/* Color variables from theme.css – grouped by palette */
const COLOR_GROUPS: { group: string; swatches: { name: string; var: string; bg?: boolean }[] }[] = [
  {
    group: "White",
    swatches: [{ name: "white", var: "--color-white", bg: true }],
  },
  {
    group: "Gray",
    swatches: [
      { name: "gray-50", var: "--color-gray-50", bg: true },
      { name: "gray-100", var: "--color-gray-100", bg: true },
      { name: "gray-200", var: "--color-gray-200", bg: true },
      { name: "gray-300", var: "--color-gray-300", bg: true },
      { name: "gray-400", var: "--color-gray-400", bg: true },
      { name: "gray-500", var: "--color-gray-500", bg: true },
      { name: "gray-600", var: "--color-gray-600", bg: true },
      { name: "gray-700", var: "--color-gray-700", bg: true },
      { name: "gray-900", var: "--color-gray-900", bg: true },
    ],
  },
  {
    group: "Brand",
    swatches: [
      { name: "brand-500", var: "--color-brand-500", bg: true },
      { name: "brand-600", var: "--color-brand-600", bg: true },
      { name: "brand-700", var: "--color-brand-700", bg: true },
    ],
  },
  {
    group: "Error",
    swatches: [
      { name: "error-500", var: "--color-error-500", bg: true },
      { name: "error-600", var: "--color-error-600", bg: true },
    ],
  },
  {
    group: "Text",
    swatches: [
      { name: "text-primary", var: "--color-text-primary", bg: false },
      { name: "text-secondary", var: "--color-text-secondary", bg: false },
      { name: "text-tertiary", var: "--color-text-tertiary", bg: false },
    ],
  },
  {
    group: "Background",
    swatches: [
      { name: "bg-primary", var: "--color-bg-primary", bg: true },
      { name: "bg-secondary", var: "--color-bg-secondary", bg: true },
      { name: "bg-tertiary", var: "--color-bg-tertiary", bg: true },
      { name: "bg-brand-solid", var: "--color-bg-brand-solid", bg: true },
    ],
  },
  {
    group: "Border",
    swatches: [
      { name: "border-primary", var: "--color-border-primary", bg: true },
      { name: "border-secondary", var: "--color-border-secondary", bg: true },
    ],
  },
];

const FONT_ITEMS: { name: string; var: string; sample: string }[] = [
  { name: "Body", var: "--font-body", sample: "The quick brown fox jumps over the lazy dog. 0123456789" },
  { name: "Display", var: "--font-display", sample: "The quick brown fox" },
  { name: "Mono", var: "--font-mono", sample: "const x = 42; // code" },
];

const FONT_SIZE_ITEMS: { name: string; class: string }[] = [
  { name: "text-xs", class: "text-xs" },
  { name: "text-sm", class: "text-sm" },
  { name: "text-md", class: "text-md" },
  { name: "text-lg", class: "text-lg" },
  { name: "text-xl", class: "text-xl" },
  { name: "text-display-xs", class: "text-display-xs" },
  { name: "text-display-sm", class: "text-display-sm" },
  { name: "text-display-md", class: "text-display-md" },
  { name: "text-display-lg", class: "text-display-lg" },
  { name: "text-display-xl", class: "text-display-xl" },
];

const ELEMENT_EXPORTS = [
  "Button", "RoundButton", "ButtonGroup", "Input", "Textarea", "PrivacyCheckbox",
  "Form", "FormContainer", "InputGroup", "Label", "HintText", "Select", "SelectItem",
  "NativeSelect", "PhotoWithFallback", "Badge", "BadgeWithDot", "BadgeGroup",
  "RatingStars", "RatingBadge", "Tooltip", "Avatar", "AvatarLabelGroup", "VerifiedTick",
  "Breadcrumb", "FeaturedIcon", "PaginationPageDefault", "PaginationPageMinimalCenter",
  "GoogleMap", "MarkdownRenderer", "Pagination", "Carousel", "CarouselSectionWrapper",
  "ComboBox", "VideoModal", "VideoPlayButton",
];

const SECTION_EXPORTS = [
  "HeroHome", "ServicesHome", "AboutHome", "TestimonialsHome", "TestimonialsGrid",
  "FAQHome", "BlogSection", "ContactSection", "FooterHome", "HeaderNavigation",
  "GenericHeaderComponent", "StatisticsSection", "ValuesSection", "TeamGrid",
  "LocationGrid", "LocationDetailsSection", "ServicesGrid", "SocialMediaGrid",
  "JobGallery", "BlogHome", "BlogGallery", "BlogPostSection", "ContactHome",
  "FAQGrid", "FAQHero", "GenericTextHero", "LocationDetailHero", "ServiceDetailHero",
  "JobDetailHero", "JobDetailSection", "PolicyDocumentSection", "SocialMediaHero",
  "TestimonialsHero", "HomeHeroComponent", "JobApplicationForm",
];

function sectionSlug(name: string): string {
  return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
}

const MINIMAL_SITE_CONFIG = {
  site: { title: "Gallery", description: "", theme: "classic" as Theme },
  navigation: {
    header: [{ label: "Home", href: "/" }, { label: "Services", href: "/services" }, { label: "Contact", href: "/contact" }],
    footer: [
      [{ label: "Home", href: "/" }, { label: "Contact", href: "/contact" }],
      [{ label: "Privacy", href: "/privacy" }, { label: "Terms", href: "/terms" }],
    ],
  },
};

/** Per-page hero overrides so each page shows the correct header (mock data has "About Us" in hero_generic). */
export type HeroOverrides = {
  genericTextHero?: { label?: string; title?: string; subtitle?: string };
  faqHero?: { label?: string; title?: string; subtitle?: string };
  testimonialsHero?: { title?: string; subtitle?: string };
};

/** Page definitions mirroring customer-site-template: label, section order, and hero text per route. */
export const GALLERY_PAGES: {
  id: string;
  label: string;
  sectionNames: string[];
  heroOverrides?: HeroOverrides;
}[] = [
  { id: "home", label: "Home", sectionNames: ["HeroHome", "ServicesHome", "AboutHome", "TestimonialsHome", "BlogSection", "ContactSection", "FAQHome"] },
  { id: "services", label: "Services", sectionNames: ["GenericTextHero", "ServicesGrid", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { genericTextHero: { title: "Our Services", subtitle: "Explore our comprehensive range of services" } } },
  { id: "locations", label: "Locations", sectionNames: ["GenericTextHero", "LocationGrid", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { genericTextHero: { title: "Our Locations", subtitle: "Find a location near you" } } },
  { id: "about", label: "About Us", sectionNames: ["GenericTextHero", "ValuesSection", "TeamGrid", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { genericTextHero: { title: "About Us", subtitle: "Learn more about our story and mission" } } },
  { id: "about-team", label: "Our Team", sectionNames: ["GenericTextHero", "TeamGrid", "TestimonialsHome", "BlogSection"], heroOverrides: { genericTextHero: { title: "Our Team", subtitle: "Meet the dedicated professionals behind our success" } } },
  { id: "careers", label: "Careers", sectionNames: ["GenericTextHero", "TeamGrid", "JobGallery", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { genericTextHero: { title: "Careers", subtitle: "Join our growing team and make an impact" } } },
  { id: "contact", label: "Contact", sectionNames: ["GenericTextHero", "ContactSection"], heroOverrides: { genericTextHero: { title: "Contact Us", subtitle: "We would love to hear from you" } } },
  { id: "testimonials", label: "Testimonials", sectionNames: ["TestimonialsHero", "StatisticsSection", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { testimonialsHero: { title: "Testimonials", subtitle: "See what our clients have to say" } } },
  { id: "blog", label: "Blog", sectionNames: ["BlogGallery", "TestimonialsHome", "ContactSection"] },
  { id: "faq", label: "FAQ", sectionNames: ["FAQHero", "FAQHome", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { faqHero: { title: "Frequently Asked Questions", subtitle: "Find answers to common questions about our services and policies." } } },
  { id: "social-media", label: "Social Media", sectionNames: ["GenericTextHero", "SocialMediaGrid", "TestimonialsHome", "BlogSection", "ContactSection"], heroOverrides: { genericTextHero: { title: "Social Media", subtitle: "Follow us and stay connected" } } },
  { id: "privacy-policy", label: "Privacy Policy", sectionNames: ["PolicyDocumentSection"] },
  { id: "terms-of-service", label: "Terms of Service", sectionNames: ["PolicyDocumentSection"] },
];

const selectItems = [
  { id: "botox", label: "Botox", supportingText: "30 min" },
  { id: "filler", label: "Filler", supportingText: "45 min" },
  { id: "facial", label: "Facial", supportingText: "60 min" },
];

const markdown = `
### Design System Gallery
- Validate styles in default/aman/barelux
- Catch regressions after purges
`;

function ColorsPanel() {
  return (
    <section className="space-y-8">
      <h2 className="gallery-section-title">Colors</h2>
      <p className="gallery-section-subtitle">Theme color tokens by group (raw palette and semantic).</p>
      {COLOR_GROUPS.map(({ group, swatches }) => (
        <div key={group} className="space-y-2">
          <h3 className="gallery-subsection-title">{group}</h3>
          <div className="grid gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
            {swatches.map(({ name, var: v, bg }) => (
              <div key={name} className="overflow-hidden rounded-xl ring-1 ring-gray-200">
                <div
                  className="h-20 w-full"
                  style={{ backgroundColor: bg ? `var(${v})` : undefined, color: bg ? undefined : `var(${v})` }}
                >
                  {!bg && <span className="block p-2 text-sm font-medium">Aa</span>}
                </div>
                <div className="gallery-label px-3 py-2">{name}</div>
              </div>
            ))}
          </div>
        </div>
      ))}
    </section>
  );
}

function FontsPanel() {
  return (
    <section className="space-y-8">
      <h2 className="gallery-section-title">Fonts</h2>
      <p className="gallery-section-subtitle">Font families and size scale.</p>

      <div className="space-y-4">
        <h3 className="gallery-subsection-title">Families</h3>
        <div className="gallery-panel-container space-y-4">
          {FONT_ITEMS.map(({ name, var: v, sample }) => (
            <div key={name}>
              <div className="gallery-label mb-1">{name} (var({v}))</div>
              <div style={{ fontFamily: `var(${v})`, color: '#111827' }}>{sample}</div>
            </div>
          ))}
        </div>
      </div>

      <div className="space-y-4">
        <h3 className="gallery-subsection-title">Size scale</h3>
        <div className="gallery-panel-container space-y-3">
          {FONT_SIZE_ITEMS.map(({ name, class: c }) => (
            <div key={name} className="flex items-baseline gap-4">
              <span className="gallery-label w-36 shrink-0">{name}</span>
              <span className={c} style={{ color: '#111827' }}>The quick brown fox</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function ElementsPanel() {
  const [page, setPage] = useState(1);
  const [showVideo, setShowVideo] = useState(false);

  return (
    <section className="space-y-10">
      <h2 className="gallery-section-title">Elements</h2>
      <p className="gallery-section-subtitle">Retained design-system elements and smoke checks.</p>

      <div className="gallery-panel-container space-y-6">
        <h3 className="gallery-subsection-title">Buttons and Badges</h3>
        <div className="flex flex-wrap items-center gap-3">
          <Button>Primary</Button>
          <Button color="secondary">Secondary</Button>
          <Button color="link-gray">Link</Button>
          <RoundButton icon={Star01} />
        </div>
        <div className="flex flex-wrap items-center gap-3">
          <Badge color="brand">Brand</Badge>
          <BadgeWithDot color="success">Healthy</BadgeWithDot>
          <BadgeGroup addonText="New" color="brand">Gallery</BadgeGroup>
        </div>
      </div>

      <div className="gallery-panel-container space-y-6">
        <h3 className="gallery-subsection-title">Inputs</h3>
        <div className="grid gap-4 md:grid-cols-2">
          <Input label="Full name" placeholder="Jane Doe" hint="Required field" />
          <Input label="Location" placeholder="Los Angeles" icon={MarkerPin02} />
          <Textarea label="Notes" placeholder="Add booking notes..." />
          <NativeSelect
            label="Native select"
            options={[
              { label: "Aman", value: "aman" },
              { label: "Barelux", value: "barelux" },
            ]}
          />
          <Select label="Service" placeholder="Choose a service" items={selectItems}>
            {(item: { id: string; label?: string; supportingText?: string }) => <SelectItem {...item} />}
          </Select>
        </div>
      </div>

      <div className="gallery-panel-container space-y-6">
        <h3 className="gallery-subsection-title">Media and Rich Content</h3>
        <div className="grid gap-4 md:grid-cols-2">
          <PhotoWithFallback
            src="https://images.unsplash.com/photo-1570172619644-dfd03ed5d881?w=1200&q=80"
            alt="Treatment room"
            className="h-52 w-full rounded-xl object-cover"
          />
          <div className="rounded-xl bg-secondary p-4">
            <MarkdownRenderer>{markdown}</MarkdownRenderer>
          </div>
        </div>
      </div>

      <div className="gallery-panel-container space-y-6">
        <h3 className="gallery-subsection-title">Avatar and Icon</h3>
        <div className="flex items-center gap-4">
          <Avatar name="Rahul Jaswa" size="md" />
          <FeaturedIcon icon={Calendar} color="brand" size="lg" />
        </div>
      </div>

      <div className="gallery-panel-container space-y-6">
        <h3 className="gallery-subsection-title">Pagination and Modal</h3>
        <PaginationPageDefault page={page} total={8} onPageChange={setPage} />
        <div className="flex items-center gap-3">
          <VideoPlayButton onClick={() => setShowVideo(true)} />
        </div>
        <VideoModal
          isOpen={showVideo}
          onClose={() => setShowVideo(false)}
          videoUrl="https://www.youtube.com/embed/dQw4w9WgXcQ"
        />
      </div>

      <div className="gallery-panel-secondary">
        <h3 className="gallery-subsection-title mb-3">Export inventory</h3>
        <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
          {ELEMENT_EXPORTS.map((name) => (
            <div key={name} className="gallery-inventory-item">{name}</div>
          ))}
        </div>
      </div>
    </section>
  );
}

/** Minimal fallbacks when mock_data is missing or a key is empty */
const FALLBACK_FAQS = [
  { id: 1, question: "How do I book?", answer: "Use the form or call.", answer_markdown: "Use the booking form or call us.", featured: false, sort_order: 0, created_at: "", updated_at: "" },
  { id: 2, question: "Cancellation policy?", answer: "Cancel 24h in advance.", answer_markdown: "Please cancel at least 24 hours in advance.", featured: false, sort_order: 1, created_at: "", updated_at: "" },
];
const FALLBACK_STATISTICS = { title: "By the numbers", subtitle: "Sample stats.", statistics: [{ number: "500+", label: "Happy clients", icon: "users" }, { number: "10", label: "Years experience", icon: "calendar" }, { number: "4.9", label: "Average rating", icon: "star" }] };
const FALLBACK_VALUES = { title: "Our values", subtitle: "What we stand for.", values: [{ title: "Quality", description: "Quality care.", icon: "star", color: "brand" }, { title: "Trust", description: "Transparency.", icon: "star", color: "brand" }, { title: "Care", description: "Personalized attention.", icon: "star", color: "brand" }] };
const FALLBACK_ABOUT = { title: "About us", subtitle: "Sample about copy.", ctaText: "Learn more", values: [{ id: "1", title: "Our mission", description: "Exceptional service.", icon: "star" }, { id: "2", title: "Our approach", description: "Evidence-based.", icon: "star" }] };
const FALLBACK_HERO_GENERIC = { title: "Welcome to the design system", subtitle: "Sections use data from app/mock_data (or fallbacks)." };
const FALLBACK_HERO_HOME = { headline: "Hero headline", subhead: "Supporting copy. Theme and typography apply." };
const FALLBACK_FAQ_HERO = { title: "Frequently asked questions", subtitle: "Search or browse below." };
const FALLBACK_FAQ_HOME = { title: "Common questions", subtitle: "Expand to read answers.", maxItems: 5 };

export interface SectionMockData {
  faqs?: unknown[] | null;
  statistics?: { title?: string; subtitle?: string; statistics?: Array<{ number?: string; value?: string; label: string; icon?: string }> } | null;
  values?: { title?: string; subtitle?: string; values?: Array<{ title: string; description: string; icon?: string; color?: string }> } | null;
  aboutSection?: { title?: string; subtitle?: string; ctaText?: string; values?: Array<{ id?: string; title: string; description: string; icon?: string }> } | null;
  heroGeneric?: { label?: string; title?: string; subtitle?: string } | null;
  heroHome?: { headline?: string; subhead?: string } | null;
  faqHero?: { label?: string; title?: string; subtitle?: string } | null;
  faqHome?: { title?: string; subtitle?: string; maxItems?: number } | null;
  companyInformation?: unknown | null;
  websitePhotos?: unknown[] | null;
  services?: unknown[] | null;
  testimonials?: unknown[] | null;
  blogPosts?: unknown[] | null;
}

function buildSectionBlocks(sectionData?: SectionMockData | null, heroOverrides?: HeroOverrides | null): Record<string, React.ReactNode> {
  const faqs = (sectionData?.faqs?.length ? sectionData.faqs : FALLBACK_FAQS) as typeof FALLBACK_FAQS;
  const statistics = sectionData?.statistics ?? FALLBACK_STATISTICS;
  const values = sectionData?.values ?? FALLBACK_VALUES;
  const aboutSection = sectionData?.aboutSection ?? FALLBACK_ABOUT;
  type HeroLabelTitleSubtitle = { label?: string; title?: string; subtitle?: string };
  const heroGeneric: HeroLabelTitleSubtitle = heroOverrides?.genericTextHero
    ? { ...FALLBACK_HERO_GENERIC, ...heroOverrides.genericTextHero }
    : (sectionData?.heroGeneric ?? FALLBACK_HERO_GENERIC);
  const heroHome = sectionData?.heroHome ?? FALLBACK_HERO_HOME;
  const faqHero: HeroLabelTitleSubtitle = heroOverrides?.faqHero
    ? { ...FALLBACK_FAQ_HERO, ...heroOverrides.faqHero }
    : (sectionData?.faqHero ?? FALLBACK_FAQ_HERO);
  const testimonialsHero = heroOverrides?.testimonialsHero
    ? { ...{ title: "Testimonials", subtitle: "What clients say." }, ...heroOverrides.testimonialsHero }
    : { title: "Testimonials", subtitle: "What clients say." };
  const faqHome = sectionData?.faqHome ?? FALLBACK_FAQ_HOME;
  const services = sectionData?.services ?? [];
  const testimonials = sectionData?.testimonials ?? [];
  const blogPosts = sectionData?.blogPosts ?? [];
  const companyInfo = sectionData?.companyInformation ?? null;
  const websitePhotos = sectionData?.websitePhotos ?? null;

  return {
    HeroHome: <HeroHome headline={heroHome.headline} subhead={heroHome.subhead} websitePhotos={websitePhotos} />,
    ServicesHome: <ServicesHome services={Array.isArray(services) ? services : []} title="Our Services" subtitle="Explore our treatments." />,
    AboutHome: <AboutHome title={aboutSection.title} subtitle={aboutSection.subtitle} values={aboutSection.values ?? []} ctaText={aboutSection.ctaText} companyInformation={companyInfo} websitePhotos={websitePhotos} />,
    TestimonialsHome: <TestimonialsHome testimonials={Array.isArray(testimonials) ? testimonials : []} title="What Our Clients Say" subtitle="Real stories." />,
    TestimonialsGrid: <TestimonialsGrid testimonials={Array.isArray(testimonials) ? testimonials : []} title="Testimonials" />,
    FAQHome: <FAQHome faqs={faqs} title={faqHome.title} subtitle={faqHome.subtitle} maxItems={faqHome.maxItems} />,
    BlogSection: <BlogSection blogPosts={Array.isArray(blogPosts) ? blogPosts : []} title="Latest News" subtitle="From our practice." />,
    ContactSection: <ContactSection websitePhotos={websitePhotos} title="Get in Touch" subtitle="We'd love to hear from you." />,
    FooterHome: <FooterHome config={MINIMAL_SITE_CONFIG} companyInformation={companyInfo} websitePhotos={websitePhotos} />,
    HeaderNavigation: <HeaderNavigation config={MINIMAL_SITE_CONFIG} companyInformation={companyInfo} websitePhotos={websitePhotos} />,
    GenericHeaderComponent: <GenericHeaderComponent items={[{ label: "Home", href: "/" }, { label: "Services", href: "/services" }]} />,
    StatisticsSection: <StatisticsSection title={statistics.title} subtitle={statistics.subtitle} statistics={statistics.statistics ?? []} />,
    ValuesSection: <ValuesSection title={values.title} subtitle={values.subtitle} values={values.values ?? []} />,
    TeamGrid: <TeamGrid teamMembers={[]} title="Our Team" subtitle="Meet the team." />,
    LocationGrid: <LocationGrid locations={[]} companyInformation={companyInfo} title="Locations" subtitle="Visit us." />,
    LocationDetailsSection: <LocationDetailsSection location={null} />,
    ServicesGrid: <ServicesGrid services={Array.isArray(services) ? services : []} title="Services" subtitle="What we offer." />,
    SocialMediaGrid: <SocialMediaGrid socialPosts={[]} title="Social" subtitle="Follow us." />,
    JobGallery: <JobGallery jobs={[]} websitePhotos={websitePhotos} title="Careers" />,
    BlogHome: <BlogHome blogPosts={Array.isArray(blogPosts) ? blogPosts : []} title="Blog" subtitle="News and insights." />,
    BlogGallery: <BlogGallery blogPosts={Array.isArray(blogPosts) ? blogPosts : []} title="Articles" />,
    BlogPostSection: <BlogPostSection blogPost={Array.isArray(blogPosts) && blogPosts[0] ? blogPosts[0] : null} />,
    ContactHome: <ContactHome websitePhotos={websitePhotos} title="Contact" subtitle="Get in touch." />,
    FAQGrid: <FAQGrid faqs={faqs} companyInformation={companyInfo} title="FAQ" />,
    FAQHero: <FAQHero label={faqHero?.label} title={faqHero?.title} subtitle={faqHero?.subtitle} />,
    GenericTextHero: <GenericTextHero label={heroGeneric?.label} title={heroGeneric?.title} subtitle={heroGeneric?.subtitle} />,
    LocationDetailHero: <LocationDetailHero location={null} companyInformation={companyInfo} />,
    ServiceDetailHero: <ServiceDetailHero service={Array.isArray(services) && services[0] ? services[0] : null} />,
    JobDetailHero: <JobDetailHero job={null} />,
    JobDetailSection: <JobDetailSection job={null} />,
    PolicyDocumentSection: <PolicyDocumentSection title="Privacy Policy" content="Sample policy content." />,
    SocialMediaHero: <SocialMediaHero title="Social Media" subtitle="Follow us." />,
    TestimonialsHero: <TestimonialsHero title={testimonialsHero.title} subtitle={testimonialsHero.subtitle} />,
    HomeHeroComponent: <HomeHeroComponent headline={heroHome.headline} subhead={heroHome.subhead} />,
    JobApplicationForm: <JobApplicationForm jobSlug="demo" formDefinition={null} />,
  };
}

function SectionsPanel({ sectionData, activeSectionSlug }: { sectionData?: SectionMockData | null; activeSectionSlug?: string }) {
  const sectionBlocks = buildSectionBlocks(sectionData);

  useEffect(() => {
    if (activeSectionSlug) {
      document.getElementById(`section-${activeSectionSlug}`)?.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  }, [activeSectionSlug]);

  return (
    <section className="space-y-8">
      <div>
        <h2 className="gallery-section-title">Sections</h2>
        <p className="gallery-section-subtitle">Every section component. Use the sidebar to jump to a section. Data from app/mock_data.</p>
      </div>

      <div className="space-y-8">
        {SECTION_EXPORTS.map((name) => {
          const slug = sectionSlug(name);
          const content = sectionBlocks[name];
          return (
            <div key={name} id={`section-${slug}`} className="scroll-mt-28 space-y-3">
              <h3 className="gallery-subsection-title text-xl md:text-2xl">{name}</h3>
              <div className="gallery-preview-box">
                {content ?? <p className="p-4 text-sm gallery-label">Not rendered (missing mapping).</p>}
              </div>
            </div>
          );
        })}
      </div>
    </section>
  );
}

function PagesPanel({ sectionData, activePage }: { sectionData?: SectionMockData | null; activePage: string }) {
  const page = GALLERY_PAGES.find((p) => p.id === activePage) ?? GALLERY_PAGES[0];
  const sectionBlocks = buildSectionBlocks(sectionData, page.heroOverrides ?? undefined);

  return (
    <section className="space-y-6">
      <div>
        <h2 className="gallery-section-title">Pages</h2>
        <p className="gallery-section-subtitle">Full page preview with header and footer. Use the sidebar to switch pages.</p>
      </div>

      {/* Single page: one container with header, sections stacked (no per-section container), footer */}
      <div className="gallery-preview-box">
        {sectionBlocks.HeaderNavigation}
        <div className="min-w-0">
          {page.sectionNames.map((name) => {
            const content = sectionBlocks[name];
            return <div key={name}>{content ?? <p className="p-4 text-sm gallery-label">Not rendered (missing mapping).</p>}</div>;
          })}
        </div>
        {sectionBlocks.FooterHome}
      </div>
    </section>
  );
}

export interface DesignGalleryProps {
  theme: Theme;
  onThemeChange: (theme: Theme) => void;
  activeSection: GallerySection;
  onSectionChange: (section: GallerySection) => void;
  sectionData?: SectionMockData | null;
  /** When activeSection is "pages", which page to show. */
  activePage?: string;
  onPageChange?: (pageId: string) => void;
  /** When activeSection is "sections", which section to scroll to (slug). */
  activeSectionSlug?: string;
  onSectionSlugChange?: (slug: string) => void;
}

function GalleryContent({
  theme,
  onThemeChange,
  activeSection,
  onSectionChange,
  sectionData,
  activePage = GALLERY_PAGES[0].id,
  onPageChange,
  activeSectionSlug,
  onSectionSlugChange,
}: DesignGalleryProps) {
  const dataTheme = theme === "classic" ? undefined : theme;
  const [sectionsExpanded, setSectionsExpanded] = useState(activeSection === "sections");
  const [pagesExpanded, setPagesExpanded] = useState(activeSection === "pages");

  useEffect(() => {
    if (activeSection === "sections" || activeSection === "pages") {
      queueMicrotask(() => {
        if (activeSection === "sections") setSectionsExpanded(true);
        if (activeSection === "pages") setPagesExpanded(true);
      });
    }
  }, [activeSection]);

  const isSectionsActive = activeSection === "sections";
  const isPagesActive = activeSection === "pages";

  const handleSectionsClick = () => {
    onSectionChange("sections");
    setSectionsExpanded((e) => !e);
    setPagesExpanded(false);
  };
  const handlePagesClick = () => {
    onSectionChange("pages");
    setPagesExpanded((e) => !e);
    setSectionsExpanded(false);
  };
  const handleSectionSlugClick = (slug: string) => {
    onSectionChange("sections");
    setSectionsExpanded(true);
    onSectionSlugChange?.(slug);
  };
  const handlePageClick = (pageId: string) => {
    onSectionChange("pages");
    setPagesExpanded(true);
    onPageChange?.(pageId);
  };

  return (
    <div className="gallery-root">
        <header className="gallery-header">
          <h1 className="gallery-header-title">keystone-design-bootstrap</h1>
          <div className="gallery-header-select">
            <NativeSelect
              options={THEMES}
              value={theme}
              onChange={(e: ChangeEvent<HTMLSelectElement>) => onThemeChange(e.target.value as Theme)}
            />
          </div>
        </header>

        <div className="flex">
          <aside className="gallery-sidebar">
            <nav className="gallery-sidebar-nav">
              {SIDEBAR_ITEMS.filter(({ id }) => id !== "sections" && id !== "pages").map(({ id, label }) => (
                <button
                  key={id}
                  type="button"
                  onClick={() => { onSectionChange(id); setSectionsExpanded(false); setPagesExpanded(false); }}
                  className={`gallery-nav-button ${activeSection === id ? "gallery-nav-button-active" : ""}`}
                >
                  {label}
                </button>
              ))}

              {/* Sections: collapsible with nested section list */}
              <div className="gallery-nav-section">
                <button
                  type="button"
                  onClick={handleSectionsClick}
                  className={`gallery-nav-button flex items-center justify-between ${isSectionsActive ? "gallery-nav-button-active" : ""}`}
                >
                  Sections
                  <span className="gallery-nav-arrow" aria-hidden>{sectionsExpanded ? "▲" : "▼"}</span>
                </button>
                {sectionsExpanded && (
                  <div className="gallery-nav-nested">
                    {SECTION_EXPORTS.map((name) => {
                      const slug = sectionSlug(name);
                      const isSelected = isSectionsActive && activeSectionSlug === slug;
                      return (
                        <button
                          key={slug}
                          type="button"
                          onClick={() => handleSectionSlugClick(slug)}
                          className={`gallery-nav-nested-button ${isSelected ? "gallery-nav-nested-button-active" : ""}`}
                        >
                          {name}
                        </button>
                      );
                    })}
                  </div>
                )}
              </div>

              {/* Pages: collapsible with nested page list */}
              <div className="gallery-nav-section">
                <button
                  type="button"
                  onClick={handlePagesClick}
                  className={`gallery-nav-button flex items-center justify-between ${isPagesActive ? "gallery-nav-button-active" : ""}`}
                >
                  Pages
                  <span className="gallery-nav-arrow" aria-hidden>{pagesExpanded ? "▲" : "▼"}</span>
                </button>
                {pagesExpanded && (
                  <div className="gallery-nav-nested">
                    {GALLERY_PAGES.map((page) => {
                      const isSelected = isPagesActive && activePage === page.id;
                      return (
                        <button
                          key={page.id}
                          type="button"
                          onClick={() => handlePageClick(page.id)}
                          className={`gallery-nav-nested-button ${isSelected ? "gallery-nav-nested-button-active" : ""}`}
                        >
                          {page.label}
                        </button>
                      );
                    })}
                  </div>
                )}
              </div>
            </nav>
          </aside>

          <main className="gallery-main">
            <div data-theme={dataTheme}>
              {activeSection === "colors" && <ColorsPanel />}
              {activeSection === "fonts" && <FontsPanel />}
              {activeSection === "elements" && <ElementsPanel />}
              {activeSection === "sections" && <SectionsPanel sectionData={sectionData} activeSectionSlug={activeSectionSlug} />}
              {activeSection === "pages" && <PagesPanel sectionData={sectionData} activePage={activePage} />}
            </div>
          </main>
        </div>
      </div>
  );
}

/** Renders the design gallery. When used inside the Next app, pass state from the app so hooks run in the same React tree (avoids useState-in-null context). */
export function DesignGallery(props: DesignGalleryProps) {
  return <GalleryContent {...props} />;
}
