import { useMemo } from 'react';
import {
  FeatureGridBlock,
  HeroBlock,
  MarketingTemplate,
  StatsPanel,
  type FeatureGridBlockProps,
  type StatItem,
} from '@shared';
import { useSiteDefinitionStore } from '../../state/siteDefinitionStore';
import { useBuilderStore } from '../../state/builderStore';
import type { PageBlock, PageBlueprint, SiteStructure } from '../../types/siteBuilder';

type StructuredContent = Record<string, unknown> & {
  items?: unknown[];
  eyebrow?: string;
  ctaLabel?: string;
  supportingCopy?: string;
  columns?: number;
};

export function PreviewCanvas() {
  const { structure, pages, selectedSlug, selectPage } = useSiteDefinitionStore();
  const { selectedPageIds, togglePageSelection, selectAllPages, clearPageSelection, activeBlueprint } =
    useBuilderStore();

  const page = useMemo(() => {
    if (structure?.pages?.length) {
      return structure.pages.find((p) => p.slug === selectedSlug) ?? structure.pages[0];
    }
    return pages.find((p) => p.slug === selectedSlug) ?? pages[0];
  }, [structure, pages, selectedSlug]);

  if (!structure && !pages.length) {
    return (
      <div className="preview-placeholder">
        <p>Generate a blueprint to see live previews of every page.</p>
      </div>
    );
  }

  const navItems = structure?.site?.primary_navigation ?? pages.map((p) => p.slug);
  const blocks = getBlocks(page);
  const heroBlock = blocks.find((block) => normalizeType(block.type) === 'hero');
  const contentBlocks = heroBlock ? blocks.filter((block) => block !== heroBlock) : blocks;

  const heroSection =
    heroBlock || page
      ? renderBlock(heroBlock ?? buildFallbackHero(page, structure))
      : null;

  const sectionNodes =
    contentBlocks.length > 0
      ? contentBlocks.map((block, index) => <div key={`${block.type}-${index}`}>{renderBlock(block)}</div>)
      : buildFallbackSections(page);

  const sidebar = (
    <div className="preview-sidebar">
      <p className="preview-label">Page objective</p>
      <h4>{page?.objective ?? 'Launch a high-converting page'}</h4>
      <ul className="preview-sidebar__list">
        {buildSidebarInsights(page, structure).map((insight) => (
          <li key={insight.label}>
            <span>{insight.label}</span>
            <strong>{insight.value}</strong>
          </li>
        ))}
      </ul>
    </div>
  );

  // Only show page selection if we have actual PageBlueprint objects with IDs
  const hasPageBlueprints = pages.length > 0 && pages.every((p) => p.id > 0);

  const allSelected = hasPageBlueprints && pages.length > 0 && selectedPageIds.length === pages.length;
  const someSelected = hasPageBlueprints && selectedPageIds.length > 0 && selectedPageIds.length < pages.length;

  return (
    <div className="preview-canvas">
      <div className="preview-nav">
        {hasPageBlueprints && activeBlueprint && (
          <div className="preview-page-selection" style={{ marginBottom: '12px', padding: '8px', background: '#f5f5f5', borderRadius: '4px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '8px' }}>
              <input
                type="checkbox"
                checked={allSelected}
                ref={(input) => {
                  if (input) input.indeterminate = someSelected;
                }}
                onChange={(e) => {
                  if (e.target.checked) {
                    selectAllPages();
                  } else {
                    clearPageSelection();
                  }
                }}
                style={{ cursor: 'pointer' }}
              />
              <label style={{ cursor: 'pointer', fontSize: '14px', fontWeight: '500' }}>
                Select pages for bulk generation ({selectedPageIds.length} selected)
              </label>
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
              {pages.map((p) => {
                const isSelected = selectedPageIds.includes(p.id);
                return (
                  <label
                    key={p.id}
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      gap: '4px',
                      cursor: 'pointer',
                      fontSize: '12px',
                      padding: '4px 8px',
                      background: isSelected ? '#e3f2fd' : 'white',
                      border: `1px solid ${isSelected ? '#2196f3' : '#ddd'}`,
                      borderRadius: '4px',
                    }}
                  >
                    <input
                      type="checkbox"
                      checked={isSelected}
                      onChange={() => togglePageSelection(p.id)}
                      style={{ cursor: 'pointer' }}
                    />
                    <span>{p.title || p.slug.replace('-', ' ')}</span>
                  </label>
                );
              })}
            </div>
          </div>
        )}
        {navItems?.map((slug) => (
          <button
            key={slug}
            type="button"
            onClick={() => selectPage(slug)}
            className={slug === (page?.slug ?? '') ? 'is-active' : ''}
          >
            {slug.replace('-', ' ')}
          </button>
        ))}
      </div>

      <MarketingTemplate hero={heroSection} sections={sectionNodes} sidebar={sidebar} />
    </div>
  );
}

function getBlocks(
  page: (SiteStructure['pages'][number] & { blocks_json?: PageBlock[] }) | PageBlueprint | undefined,
) {
  if (!page) return [];
  const fromStructure = (page as { blocks?: PageBlock[] }).blocks;
  if (Array.isArray(fromStructure)) return fromStructure;
  const fromBlueprint = (page as PageBlueprint).blocks_json;
  return Array.isArray(fromBlueprint) ? fromBlueprint : [];
}

function renderBlock(block?: PageBlock) {
  if (!block) return null;
  const type = normalizeType(block.type);
  const structuredContent = extractStructuredContent(block);
  const listContent = extractListContent(block, structuredContent);

  if (type === 'hero') {
    return (
      <HeroBlock
        eyebrow={structuredContent.eyebrow as string | undefined}
        title={block.heading ?? 'Untitled hero'}
        subtitle={block.subheading ?? (structuredContent.supportingCopy as string | undefined)}
        ctaLabel={(structuredContent.ctaLabel as string | undefined) ?? undefined}
        supportingContent={
          listContent.length > 0 ? (
            <ul>
              {listContent.map((item) => (
                <li key={String(item)}>{String(item)}</li>
              ))}
            </ul>
          ) : undefined
        }
      />
    );
  }

  if (type === 'feature-grid' || type === 'features' || type === 'value-props') {
    const features = toFeatureList(listContent, structuredContent.items);
    const columns = normalizeColumns(structuredContent.columns, features.length);
    return <FeatureGridBlock heading={block.heading} features={features} columns={columns} />;
  }

  if (type === 'stats' || type === 'metrics') {
    const stats = toStatItems(listContent, structuredContent.items, block);
    if (!stats.length) return defaultBlock(block);
    return <StatsPanel heading={block.heading} stats={stats} />;
  }

  return defaultBlock(block);
}

function defaultBlock(block: PageBlock) {
  return (
    <div className="preview-block preview-block--legacy">
      {block.heading && <h4>{block.heading}</h4>}
      {block.subheading && <p>{block.subheading}</p>}
      {Array.isArray(block.content) && (
        <ul>
          {block.content.map((item) => (
            <li key={item}>{item}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

function normalizeType(type?: string) {
  return (type ?? '').toLowerCase();
}

function extractStructuredContent(block: PageBlock): StructuredContent {
  if (Array.isArray(block.content)) {
    return {};
  }
  return (block.content ?? {}) as StructuredContent;
}

function extractListContent(block: PageBlock, structuredContent: StructuredContent): unknown[] {
  if (Array.isArray(block.content)) {
    return block.content;
  }
  if (Array.isArray(structuredContent.items)) {
    return structuredContent.items;
  }
  return [];
}

function toFeatureList(listItems: unknown[], structuredItems?: unknown[]): FeatureGridBlockProps['features'] {
  const source = structuredItems && Array.isArray(structuredItems) && structuredItems.length > 0 ? structuredItems : listItems;
  return source.map((item) => {
    if (typeof item === 'string') {
      return { title: item };
    }
    if (typeof item === 'object' && item) {
      const record = item as Record<string, unknown>;
      return {
        title: String(record.title ?? record.heading ?? 'Feature'),
        description: record.description ? String(record.description) : undefined,
        icon: record.icon ? String(record.icon) : undefined,
      };
    }
    return { title: String(item) };
  });
}

function toStatItems(
  listItems: unknown[],
  structuredItems: unknown[] | undefined,
  block: PageBlock,
): StatItem[] {
  const source = structuredItems && Array.isArray(structuredItems) && structuredItems.length > 0 ? structuredItems : listItems;
  return source
    .map((item, index) => {
      if (typeof item === 'string') {
        return {
          label: block.heading ?? `Metric ${index + 1}`,
          value: item,
        };
      }
      if (typeof item === 'object' && item) {
        const record = item as Record<string, unknown>;
        const label = record.label ?? record.title ?? `Metric ${index + 1}`;
        const value = record.value ?? record.metric ?? record.score;
        if (!value) return null;
        return {
          label: String(label),
          value: String(value),
          description: record.description ? String(record.description) : undefined,
        };
      }
      return null;
    })
    .filter((stat): stat is StatItem => Boolean(stat));
}

function normalizeColumns(
  candidate: StructuredContent['columns'],
  featureCount: number,
): FeatureGridBlockProps['columns'] {
  const inferred = typeof candidate === 'number' ? candidate : featureCount >= 4 ? 4 : featureCount === 2 ? 2 : 3;
  if (inferred <= 2) return 2;
  if (inferred >= 4) return 4;
  return 3;
}

function buildFallbackHero(
  page: SiteStructure['pages'][number] | PageBlueprint | undefined,
  structure: SiteStructure | undefined,
): PageBlock {
  return {
    type: 'hero',
    heading: page?.title ?? 'Site Builder preview',
    subheading: structure?.site?.hero_message ?? 'Preview updates as the AI hydrates your blueprint.',
    content: Array.isArray(structure?.site?.secondary_navigation) ? structure?.site?.secondary_navigation : [],
  };
}

function buildFallbackSections(page: SiteStructure['pages'][number] | PageBlueprint | undefined) {
  return [
    <FeatureGridBlock
      key="fallback-features"
      heading="Generated sections"
      features={[
        { title: 'AI messaging kit', description: 'Structured copy generated for each funnel stage.' },
        { title: 'Audience resonance', description: 'Language tuned to your target segment.' },
        { title: 'Conversion spine', description: 'CTA hierarchy anchored to your objectives.' },
      ]}
    />,
    <StatsPanel
      key="fallback-stats"
      heading="Blueprint signals"
      stats={[
        { label: 'Page type', value: page?.type ?? 'Landing' },
        { label: 'Status', value: page?.status ?? 'Draft' },
        { label: 'Blocks', value: '0' },
      ]}
    />,
  ];
}

function buildSidebarInsights(
  page: SiteStructure['pages'][number] | PageBlueprint | undefined,
  structure: SiteStructure | undefined,
) {
  return [
    {
      label: 'Primary CTA',
      value: page?.primary_cta ?? 'Book a demo',
    },
    {
      label: 'Tone',
      value: structure?.site?.tone ?? 'Confident & clear',
    },
    {
      label: 'Status',
      value: page?.status ?? 'Draft',
    },
  ];
}



