/* Thin dispatcher for /pricing. Reads the section list from the
 * `marketing.pricing` shared Inertia prop (shipped by HandleInertiaRequests)
 * and dispatches each section to its renderer via BLOCK_REGISTRY. Mirrors
 * `Pages/Welcome.tsx` — the plan-cards + period toggle + currency picker
 * + JSON-fetch state machinery moved to `PricingGridSection.tsx`.
 *
 * The chrome decision (AppNav vs marketing Nav) stays here because it
 * depends on auth + landing mode, both surfaced via Inertia shared props.
 * That decision also drives `showRails` for the pricing_grid renderer —
 * authed users on a non-landing-enabled deployment see app-shell chrome
 * without the marketing rails.
 */
import AppNav from '@/Components/AppNav';
import { getBlockMeta } from '@/marketing/block-registry';
import { DEFAULT_FOOTER, DEFAULT_HEADER } from '@/marketing/cms-defaults';
import {
    migrateFooter,
    migrateNav,
    migratePricing,
} from '@/marketing/cms-migrator';
import type {
    FooterConfig,
    HeaderConfig,
    PageConfig,
    Section,
} from '@/marketing/cms-types';
import PageSeo from '@/marketing/PageSeo';
import { Footer, Nav } from '@/marketing/shared';
import type { AuthUser, SharedProps } from '@/types/inertia';
import { Head, usePage } from '@inertiajs/react';
import type { ReactNode } from 'react';

type PricingPageProps = SharedProps & {
    marketing: SharedProps['marketing'] & {
        pricing?: { sections: Section[] };
    };
    /** Server-built Product + AggregateOffer JSON-LD. Null when no plans
     *  are configured (don't ship "Product with $0" placeholder data
     *  that erodes trust signals). */
    pricingJsonLd?: string | null;
};

// Defense-in-depth fallback when the shared prop is absent (early bootstrap,
// stale browser cache shipping the pre-CMS shape). Mirrors the server-side
// `MarketingDefaults::pricing()` minimum — just the mandatory pricing_grid.
const FALLBACK_PRICING: PageConfig = {
    version: 1,
    sections: [
        {
            id: 'pricing-grid',
            type: 'pricing_grid',
            enabled: true,
            showPeriodToggle: true,
            showCurrencyPicker: true,
        },
    ],
};

export default function Pricing() {
    const page = usePage<PricingPageProps>();
    const { auth, branding, marketing, landingMode, pricingJsonLd } = page.props;
    const user = auth.user;
    const siteName = branding?.site_name || 'AppShot AI';

    // Defense in depth: server already runs the migrator at the read boundary,
    // but a stale browser-cached prop or partially-deployed worker could ship
    // an older-version doc. Re-run the chain here so the renderer always sees
    // current shape.
    const navConfig = marketing?.nav
        ? migrateNav<HeaderConfig>(marketing.nav as HeaderConfig)
        : DEFAULT_HEADER;
    const footerConfig = marketing?.footer
        ? migrateFooter<FooterConfig>(marketing.footer as FooterConfig)
        : DEFAULT_FOOTER;
    const pricingConfig = marketing?.pricing
        ? migratePricing<PageConfig>(marketing.pricing as PageConfig)
        : FALLBACK_PRICING;
    const sections = pricingConfig.sections.filter((s) => s.enabled !== false);

    // App chrome when an authed user lands here in a deployment where the
    // marketing landing is disabled or login-only — they're in app-shell
    // context, so the marketing nav + footer + rails would feel out of place.
    const useAppChrome = !!user && landingMode.mode !== 'enabled';
    const showRails = !useAppChrome;

    return (
        <>
            <Head title="Pricing" />
            <PageSeo
                pageLabel="Pricing"
                override={pricingConfig.seo}
                sections={sections}
                extraJsonLd={pricingJsonLd ? [pricingJsonLd] : undefined}
            />
            <div className="flex min-h-screen flex-col bg-background font-sans text-foreground antialiased">
                {useAppChrome ? (
                    <AppNav />
                ) : (
                    <Nav
                        siteName={siteName}
                        authed={!!user}
                        branding={branding}
                        nav={navConfig}
                    />
                )}
                <main className="flex-1">
                    {sections.map((section) => (
                        <RenderedSection
                            key={section.id}
                            section={section}
                            user={user}
                            showRails={showRails}
                        />
                    ))}
                </main>
                {!useAppChrome && (
                    <Footer
                        siteName={siteName}
                        branding={branding}
                        footer={footerConfig}
                    />
                )}
            </div>
        </>
    );
}

function RenderedSection({
    section,
    user,
    showRails,
}: {
    section: Section;
    user: AuthUser | null;
    showRails: boolean;
}): ReactNode {
    const meta = getBlockMeta(section.type);
    // Unknown section type — silently skip rather than crash. Happens if
    // admin's saved data has a block type from a future version they're
    // temporarily downgraded from. The migrator chain preserves the row in
    // storage; only the renderer drops it.
    if (!meta) return null;
    const Renderer = meta.renderer;
    // pricing_grid is data-driven — needs auth state for the CTA copy + the
    // rails decision from the page chrome. Every other block type renders
    // with just its section payload.
    if (section.type === 'pricing_grid') {
        return <Renderer section={section} user={user} showRails={showRails} />;
    }
    return <Renderer section={section} />;
}
