import type { ComponentType } from 'react';
import {
    Blocks,
    Building2,
    CreditCard,
    FileQuestion,
    Hash,
    Layout,
    LayoutGrid,
    ListOrdered,
    Megaphone,
    MessageSquareQuote,
    Package,
    Sparkles,
} from 'lucide-react';

import { DEFAULT_WELCOME, defaultCustomSection } from './cms-defaults';
import type {
    CustomSection,
    FaqSection,
    FeaturesSection,
    FinalCtaSection,
    HeroSection,
    HowItWorksSection,
    KitGridSection,
    LogoWallSection,
    PricingGridSection,
    Section,
    StatsSection,
    TemplatesTeaserSection,
    TestimonialsSection,
} from './cms-types';

import { CustomSection as CustomSectionRenderer } from './sections/CustomSection';
import { FaqSection as FaqSectionRenderer } from './sections/FaqSection';
import { FeaturesSection as FeaturesSectionRenderer } from './sections/FeaturesSection';
import { FinalCtaSection as FinalCtaSectionRenderer } from './sections/FinalCtaSection';
import { HeroSection as HeroSectionRenderer } from './sections/HeroSection';
import { HowItWorksSection as HowItWorksSectionRenderer } from './sections/HowItWorksSection';
import { KitGridSectionRenderer } from './sections/KitGridSection';
import { LogoWallSection as LogoWallSectionRenderer } from './sections/LogoWallSection';
import { PricingGridSectionRenderer } from './sections/PricingGridSection';
import { StatsSection as StatsSectionRenderer } from './sections/StatsSection';
import { TemplatesTeaserSection as TemplatesTeaserSectionRenderer } from './sections/TemplatesTeaserSection';
import { TestimonialsSection as TestimonialsSectionRenderer } from './sections/TestimonialsSection';

import CustomEditor from '@/admin/marketing/sections/CustomEditor';
import FaqEditor from '@/admin/marketing/sections/FaqEditor';
import FeaturesEditor from '@/admin/marketing/sections/FeaturesEditor';
import FinalCtaEditor from '@/admin/marketing/sections/FinalCtaEditor';
import HeroEditor from '@/admin/marketing/sections/HeroEditor';
import HowItWorksEditor from '@/admin/marketing/sections/HowItWorksEditor';
import KitGridEditor from '@/admin/marketing/sections/KitGridEditor';
import LogoWallEditor from '@/admin/marketing/sections/LogoWallEditor';
import PricingGridEditor from '@/admin/marketing/sections/PricingGridEditor';
import StatsEditor from '@/admin/marketing/sections/StatsEditor';
import TemplatesTeaserEditor from '@/admin/marketing/sections/TemplatesTeaserEditor';
import TestimonialsEditor from '@/admin/marketing/sections/TestimonialsEditor';

export type BlockTypeMeta<TSection extends Section = Section> = {
    /** The discriminator value (`'hero'`, `'features'`, etc). */
    type: TSection['type'];
    /** Admin-facing label. */
    label: string;
    /** One-line description for the Add Section menu. */
    description: string;
    /** Lucide icon for the Add menu + section list. */
    icon: ComponentType<{ className?: string }>;
    /** Public renderer. Receives the section data plus any extra props
     *  (e.g. `kits` for `templates_teaser`). Typed permissively so the
     *  registry can hold heterogeneous renderer signatures. */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    renderer: ComponentType<any>;
    /** Admin editor. Lifts state via onChange. */
    editor: ComponentType<{
        value: TSection;
        onChange: (next: TSection) => void;
        errors?: Record<string, string>;
    }>;
    /** Factory returning a fresh instance with sensible defaults + new ID. */
    defaultData: () => TSection;
    /** True if multiple instances of this block type are allowed on a page. */
    allowMultiple?: boolean;
    /** True for data-driven sections like `pricing_grid` + `kit_grid` that
     *  always render. Editor hides disable + delete affordances; reorder
     *  + edit still work. Mandatory types are seeded into a page's defaults
     *  rather than admin-added — excluded from `pickOrderForPage`. */
    mandatory?: boolean;
    /** Per-page availability. Empty/undefined = available on all pages.
     *  Scope `pricing_grid` to ['pricing'] and `kit_grid` to ['templates']
     *  so admin can't add the wrong data-driven type to the wrong page. */
    pages?: Array<'welcome' | 'pricing' | 'templates' | 'about' | 'contact' | 'privacy' | 'terms' | 'refund'>;
};

function newId(): string {
    if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
        return crypto.randomUUID();
    }
    return `sec-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
}

// Clones the seed default for a given type and assigns a fresh id. Falls back
// to a minimal shell if no seed is registered (defensive — DEFAULT_WELCOME
// currently covers all 8 types).
function seedFromDefault<T extends Section>(type: T['type'], fallback: T): T {
    const template = DEFAULT_WELCOME.sections.find((s) => s.type === type);
    if (template) {
        return { ...(template as T), id: newId() };
    }
    return { ...fallback, id: newId() };
}

// Use a typed-by-key helper so each entry's renderer/editor/defaultData line
// up with the right discriminated section variant.
type RegistryShape = { [K in Section['type']]: BlockTypeMeta<Extract<Section, { type: K }>> };

export const BLOCK_REGISTRY: RegistryShape = {
    hero: {
        type: 'hero',
        label: 'Hero',
        description: 'Headline, subhead, CTAs, optional video or image card.',
        icon: Layout,
        renderer: HeroSectionRenderer,
        editor: HeroEditor,
        defaultData: () =>
            seedFromDefault<HeroSection>('hero', {
                id: '',
                type: 'hero',
                enabled: true,
                headline: '',
            }),
    },
    features: {
        type: 'features',
        label: 'Features',
        description: 'Heading, subhead, and a grid of feature cards with icons.',
        icon: LayoutGrid,
        renderer: FeaturesSectionRenderer,
        editor: FeaturesEditor,
        defaultData: () =>
            seedFromDefault<FeaturesSection>('features', {
                id: '',
                type: 'features',
                enabled: true,
                heading: '',
                items: [],
            }),
    },
    templates_teaser: {
        type: 'templates_teaser',
        label: 'Templates teaser',
        description: 'Promo strip pulling featured kits from the server.',
        icon: Sparkles,
        renderer: TemplatesTeaserSectionRenderer,
        editor: TemplatesTeaserEditor,
        defaultData: () =>
            seedFromDefault<TemplatesTeaserSection>('templates_teaser', {
                id: '',
                type: 'templates_teaser',
                enabled: true,
                heading: '',
                ctaLabel: '',
            }),
    },
    logo_wall: {
        type: 'logo_wall',
        label: 'Logo wall',
        description: 'Social-proof strip of customer / partner logos with a caption.',
        icon: Building2,
        renderer: LogoWallSectionRenderer,
        editor: LogoWallEditor,
        defaultData: () =>
            seedFromDefault<LogoWallSection>('logo_wall', {
                id: '',
                type: 'logo_wall',
                enabled: true,
                label: 'Powering teams at',
                items: [],
            }),
    },
    stats: {
        type: 'stats',
        label: 'Stats',
        description: 'Compact value + label tiles to anchor the page rhythm.',
        icon: Hash,
        renderer: StatsSectionRenderer,
        editor: StatsEditor,
        defaultData: () =>
            seedFromDefault<StatsSection>('stats', {
                id: '',
                type: 'stats',
                enabled: true,
                items: [],
            }),
    },
    how_it_works: {
        type: 'how_it_works',
        label: 'How it works',
        description: 'Numbered step-by-step list with optional time hints.',
        icon: ListOrdered,
        renderer: HowItWorksSectionRenderer,
        editor: HowItWorksEditor,
        defaultData: () =>
            seedFromDefault<HowItWorksSection>('how_it_works', {
                id: '',
                type: 'how_it_works',
                enabled: true,
                heading: '',
                items: [],
            }),
    },
    testimonials: {
        type: 'testimonials',
        label: 'Testimonials',
        description: 'Customer quotes with name, role, and avatar. Auto-hides when empty.',
        icon: MessageSquareQuote,
        renderer: TestimonialsSectionRenderer,
        editor: TestimonialsEditor,
        defaultData: () =>
            seedFromDefault<TestimonialsSection>('testimonials', {
                id: '',
                type: 'testimonials',
                enabled: true,
                heading: '',
                items: [],
            }),
    },
    faq: {
        type: 'faq',
        label: 'FAQ',
        description: 'Common questions with expandable answers.',
        icon: FileQuestion,
        renderer: FaqSectionRenderer,
        editor: FaqEditor,
        defaultData: () =>
            seedFromDefault<FaqSection>('faq', {
                id: '',
                type: 'faq',
                enabled: true,
                heading: '',
                items: [],
            }),
    },
    final_cta: {
        type: 'final_cta',
        label: 'Final CTA',
        description: 'Closing call-to-action band at the bottom of the page.',
        icon: Megaphone,
        renderer: FinalCtaSectionRenderer,
        editor: FinalCtaEditor,
        defaultData: () =>
            seedFromDefault<FinalCtaSection>('final_cta', {
                id: '',
                type: 'final_cta',
                enabled: true,
                heading: '',
            }),
    },
    custom: {
        type: 'custom',
        label: 'Custom',
        description: 'Vertical stack of atomic blocks — compose your own section.',
        icon: Blocks,
        renderer: CustomSectionRenderer,
        editor: CustomEditor as unknown as BlockTypeMeta<CustomSection>['editor'],
        defaultData: defaultCustomSection,
        allowMultiple: true,
    },
    pricing_grid: {
        type: 'pricing_grid',
        label: 'Pricing grid',
        description: 'Plan cards + period toggle + currency picker.',
        icon: CreditCard,
        renderer: PricingGridSectionRenderer,
        editor: PricingGridEditor as unknown as BlockTypeMeta<PricingGridSection>['editor'],
        defaultData: () => ({
            id: newId(),
            type: 'pricing_grid' as const,
            enabled: true,
            eyebrow: '',
            heading: '',
            subhead: '',
            showPeriodToggle: true,
            showCurrencyPicker: true,
            trustLine: '7-day money-back guarantee · Cancel anytime',
        }),
        mandatory: true,
        pages: ['pricing'],
    },
    kit_grid: {
        type: 'kit_grid',
        label: 'Kit grid',
        description: 'Featured kit + filter chips + full kit listing.',
        icon: Package,
        renderer: KitGridSectionRenderer,
        editor: KitGridEditor as unknown as BlockTypeMeta<KitGridSection>['editor'],
        defaultData: () => ({
            id: newId(),
            type: 'kit_grid' as const,
            enabled: true,
            heading: '',
            subhead: '',
            featuredKitKey: null,
            showCategories: true,
            showScreenCount: true,
        }),
        mandatory: true,
        pages: ['templates'],
    },
};

// Display order in the "Add section" menu. Mandatory + page-scoped types
// are filtered out by `pickOrderForPage` — they aren't admin-addable from
// the picker (seeded into defaults instead).
const FULL_PICK_ORDER: Section['type'][] = [
    'hero',
    'features',
    'templates_teaser',
    'logo_wall',
    'stats',
    'how_it_works',
    'testimonials',
    'faq',
    'final_cta',
    'custom',
    'pricing_grid',
    'kit_grid',
];

/** Pick-order for the admin Add-Section menu on a given page. Excludes
 *  `mandatory: true` types (they're seeded into defaults, not added)
 *  and types scoped to other pages via `pages`. Used by `WelcomeEditor` /
 *  `PricingEditor` / `TemplatesEditor` to populate the popover. */
export function pickOrderForPage(
    page: 'welcome' | 'pricing' | 'templates' | 'about' | 'contact' | 'privacy' | 'terms' | 'refund',
): Section['type'][] {
    return FULL_PICK_ORDER.filter((type) => {
        const meta = BLOCK_REGISTRY[type];
        if (meta.mandatory) return false;
        if (meta.pages && !meta.pages.includes(page)) return false;
        return true;
    });
}

/** Legacy export — Welcome page's original pick order. Backwards-compat
 *  for any direct consumer not yet migrated to `pickOrderForPage`. */
export const BLOCK_PICK_ORDER: Section['type'][] = pickOrderForPage('welcome');

/** Metadata for unknown types — used by the unknown-section fallback. */
export function getBlockMeta(type: string): BlockTypeMeta | null {
    return (BLOCK_REGISTRY as unknown as Record<string, BlockTypeMeta>)[type] ?? null;
}
