import { useEffect, useMemo, useState, type ReactNode } from "react";
import { getBlockComponent, type BlockContent } from "@/components/page-blocks";
import { GradeHeroBlock } from "@/components/page-blocks/GradeHeroBlock";
import { BrandscapeShell } from "@/components/BrandscapeShell";
import { PageSectionRenderer } from "@/components/PageSectionRenderer";
import { normalizeContent, getRenderableSectionBlocks, layoutToGridColumns } from "@/admin/pages/sectionLayouts";
import { resolveBlockSlug } from "@/lib/blockSlug";
import {
  buildContentPlaceholderVars,
} from "@/lib/contentPlaceholders";
import {
  findComponentLibraryContent,
  resolveEditorBlockContent,
} from "@/lib/mergeBlockContent";
import { isPbelFlyerPage } from "@/lib/sectionWidthForBlock";
import { useComponentDefaults } from "@/hooks/useComponentDefaults";
import { useSiteChrome } from "@/contexts/SiteChromeContext";
import { useSiteSettings } from "@/contexts/SiteSettingsContext";
import {
  normalizePageSettings,
  shouldHideGlobalFooter,
  shouldRenderFooterBlock,
} from "@/lib/pageFooterSettings";
import {
  collectCompetitionNavState,
  isCompetitionTargetVisible,
  resolveCompetitionTargetSlug,
  type CompetitionNavItem,
} from "@/lib/competitionNavigation";

export type CmsPageData = {
  id: number;
  title: string;
  slug: string;
  content: unknown;
  settings?: {
    showFooter?: boolean;
  } | null;
  status: string;
};

type CmsPageContentProps = {
  page: CmsPageData;
};

/** Renders CMS page sections and blocks in stored order. */
export function CmsPageContent({ page }: CmsPageContentProps) {
  const sections = useMemo(() => normalizeContent(page.content), [page.content]);
  const placeholderVars = useMemo(
    () => buildContentPlaceholderVars(sections, { pageTitle: page.title }),
    [sections, page.title],
  );
  const { components: libraryComponents } = useComponentDefaults({ source: "public" });
  const { settings } = useSiteSettings();
  const { setHasPageFooter } = useSiteChrome();
  const chromeKey = `${settings.header_layout}-${settings.footer_layout}`;

  const componentLookup = useMemo(
    () => libraryComponents.map((component) => ({
      id: component.id,
      name: component.name ?? component.slug,
      slug: component.slug,
    })),
    [libraryComponents],
  );

  const resolveSlug = useMemo(
    () => (block: {
      componentId?: number;
      componentSlug?: string;
      componentName?: string;
    }) => resolveBlockSlug({
      componentId: block.componentId ?? 0,
      componentName: block.componentName ?? "",
      componentSlug: block.componentSlug,
    }, componentLookup),
    [componentLookup],
  );

  const flatBlocks = useMemo(
    () => sections.flatMap((section) => getRenderableSectionBlocks(section)),
    [sections],
  );

  const navState = useMemo(
    () => collectCompetitionNavState(flatBlocks, componentLookup, resolveSlug),
    [flatBlocks, componentLookup, resolveSlug],
  );

  // Stable signature only — never depend on array identity or the active tab resets every render.
  const navSignature = useMemo(
    () => JSON.stringify({
      defaultTargetSlug: navState.defaultTargetSlug,
      items: navState.items.map((item) => [item.id, item.targetComponent]),
      targetSlugs: navState.targetSlugs,
    }),
    [navState.defaultTargetSlug, navState.items, navState.targetSlugs],
  );

  const [activeTargetSlug, setActiveTargetSlug] = useState(navState.defaultTargetSlug);
  const [activeCompetitionNavId, setActiveCompetitionNavId] = useState(navState.items[0]?.id ?? "");

  useEffect(() => {
    try {
      const parsed = JSON.parse(navSignature) as {
        defaultTargetSlug?: string;
        items?: Array<[string, string]>;
      };
      setActiveTargetSlug(parsed.defaultTargetSlug ?? "");
      setActiveCompetitionNavId(parsed.items?.[0]?.[0] ?? "");
    } catch {
      setActiveTargetSlug("");
      setActiveCompetitionNavId("");
    }
  }, [page.id, navSignature]);

  const pageSettings = useMemo(
    () => normalizePageSettings(page.settings),
    [page.settings],
  );

  useEffect(() => {
    setHasPageFooter(shouldHideGlobalFooter(sections, pageSettings));
    return () => setHasPageFooter(false);
  }, [sections, pageSettings, setHasPageFooter]);

  const handleCompetitionNavClick = (item: CompetitionNavItem) => {
    const targetSlug = resolveCompetitionTargetSlug(item.targetComponent, componentLookup);
    setActiveCompetitionNavId(item.id);
    if (targetSlug) {
      setActiveTargetSlug(targetSlug);
    }
  };

  if (!sections.length) {
    return (
      <div className="container mx-auto px-6 py-16 text-center text-muted-foreground">
        This page has no content yet.
      </div>
    );
  }

  return (
    <FlyerPageShell enabled={isPbelFlyerPage(sections)}>
      {sections.map((section, si) => (
        <PageSectionRenderer
          key={section.id ?? si}
          section={section}
          sectionIndex={si}
          gridTemplateColumns={layoutToGridColumns(section.layout)}
        >
          {getRenderableSectionBlocks(section).map((block, bi) => {
            const blockSlug = resolveSlug(block);
            if (!shouldRenderFooterBlock(blockSlug, pageSettings)) {
              return null;
            }
            const BlockComp = getBlockComponent(blockSlug);
            const rawContent = (block.content ?? {}) as BlockContent;
            const libraryContent = findComponentLibraryContent(
              block,
              libraryComponents,
              blockSlug
            );
            const content = resolveEditorBlockContent(rawContent, {
              blockSlug,
              libraryContent,
              pageVars: placeholderVars,
            }) as BlockContent;

            const visible = isCompetitionTargetVisible(
              block,
              navState.targetSlugs,
              activeTargetSlug,
              componentLookup,
              resolveSlug,
            );

            if (!BlockComp) {
              return (
                <div
                  key={`${si}-${bi}-${blockSlug}`}
                  className="rounded-xl border bg-card p-4 text-muted-foreground text-sm"
                  hidden={!visible}
                  aria-hidden={!visible}
                >
                  Unknown block: {block.componentName} ({blockSlug})
                </div>
              );
            }

            const isGradeHero = blockSlug === "grade-hero" || blockSlug === "design-to-impact-hero";

            return (
              <div
                key={`${si}-${bi}-${blockSlug}-${block.componentId}-${chromeKey}`}
                hidden={!visible}
                aria-hidden={!visible}
                // Keep inactive competition targets mounted so tab switches are instant.
                style={visible ? undefined : { display: "none" }}
              >
                {isGradeHero && navState.hasCompetitionNavigation ? (
                  <GradeHeroBlock
                    content={content}
                    activeCompetitionNavId={activeCompetitionNavId}
                    onCompetitionNavClick={handleCompetitionNavClick}
                  />
                ) : (
                  <BlockComp content={content} />
                )}
              </div>
            );
          })}
        </PageSectionRenderer>
      ))}
    </FlyerPageShell>
  );
}

/** One max-w-4xl py-10 shell for PBEL flyer pages (matches brandscape /course/pbel-water). */
function FlyerPageShell({ enabled, children }: { enabled: boolean; children: ReactNode }) {
  if (!enabled) return <>{children}</>;
  return (
    <BrandscapeShell variant="narrow" paddingY className="relative overflow-hidden">
      {children}
    </BrandscapeShell>
  );
}
