/**
 * ComponentRegistry — maps CanvasComponent.type to renderer implementations.
 * Supports lazy loading for expensive renderers (GeoMap, Table, PipelineBoard).
 * Falls back to ErrorNoticeRenderer for unknown or revoked types.
 */
import { lazy, Suspense } from 'react';
import type { CanvasComponent } from '../types/canvas';

// ── Eager renderers (lightweight) ─────────────────────────────────────────────
import { KpiTileRenderer } from './renderers/KpiTileRenderer';
import { ErrorNoticeRenderer } from './renderers/ErrorNoticeRenderer';
import { TimelineRenderer } from './renderers/TimelineRenderer';
import { TextCanvasRenderer } from './renderers/TextCanvasRenderer';

// ── Lazy renderers (heavier) ──────────────────────────────────────────────────
const BarChartRenderer = lazy(() => import('./renderers/BarChartRenderer').then((m) => ({ default: m.BarChartRenderer })));
const LineChartRenderer = lazy(() => import('./renderers/LineChartRenderer').then((m) => ({ default: m.LineChartRenderer })));
const GeoMapRenderer = lazy(() => import('./renderers/GeoMapRenderer').then((m) => ({ default: m.GeoMapRenderer })));
const TableRenderer = lazy(() => import('./renderers/TableRenderer').then((m) => ({ default: m.TableRenderer })));
const PipelineBoardRenderer = lazy(() => import('./renderers/PipelineBoardRenderer').then((m) => ({ default: m.PipelineBoardRenderer })));
const ActivityStreamRenderer = lazy(() => import('./renderers/ActivityStreamRenderer').then((m) => ({ default: m.ActivityStreamRenderer })));

// ── Render context ────────────────────────────────────────────────────────────

export interface ComponentRenderContext {
  tenantId: string;
  actorRole: string;
  showLineageBadges: boolean;
  density: 'compact' | 'comfortable';
  isSelected?: boolean;
  onSelect?: (componentId: string) => void;
}

// ── Skeleton ──────────────────────────────────────────────────────────────────

function ComponentSkeleton({ variant }: { variant: string }) {
  const heights: Record<string, number> = {
    chart: 280, map: 380, table: 300, kpi: 120, pipeline: 360, timeline: 300, generic: 240,
  };
  const h = heights[variant] ?? 240;
  return (
    <div
      className="rounded-2xl animate-pulse"
      style={{
        height: h,
        background: 'rgba(255,255,255,0.03)',
        border: '1px solid rgba(255,255,255,0.06)',
      }}
    />
  );
}

// ── Registry resolver ─────────────────────────────────────────────────────────

interface RegistryRendererProps {
  component: CanvasComponent;
  ctx: ComponentRenderContext;
}

export function ComponentRegistry({ component, ctx }: RegistryRendererProps) {
  const skeleton = <ComponentSkeleton variant={component.renderingHints.skeletonVariant} />;

  if (component.lifecycleState === 'revoked') {
    return (
      <ErrorNoticeRenderer
        component={{
          ...component,
          title: 'Component Revoked',
          visualizationParameters: {
            errorCode: 'component_revoked',
            message: 'This component has been revoked and can no longer be rendered.',
          },
        }}
        ctx={ctx}
      />
    );
  }

  switch (component.type) {
    case 'textCanvas':
      return <TextCanvasRenderer component={component} ctx={ctx} />;

    case 'kpiTile':
      return <KpiTileRenderer component={component} ctx={ctx} />;

    case 'errorNotice':
      return <ErrorNoticeRenderer component={component} ctx={ctx} />;

    case 'timeline':
      return <TimelineRenderer component={component} ctx={ctx} />;

    case 'barChart':
      return (
        <Suspense fallback={skeleton}>
          <BarChartRenderer component={component} ctx={ctx} />
        </Suspense>
      );

    case 'lineChart':
    case 'forecastChart':
      return (
        <Suspense fallback={skeleton}>
          <LineChartRenderer component={component} ctx={ctx} />
        </Suspense>
      );

    case 'geoMap':
    case 'heatmap':
      return (
        <Suspense fallback={skeleton}>
          <GeoMapRenderer component={component} ctx={ctx} />
        </Suspense>
      );

    case 'table':
      return (
        <Suspense fallback={skeleton}>
          <TableRenderer component={component} ctx={ctx} />
        </Suspense>
      );

    case 'pipelineBoard':
      return (
        <Suspense fallback={skeleton}>
          <PipelineBoardRenderer component={component} ctx={ctx} />
        </Suspense>
      );

    case 'activityStream':
      return (
        <Suspense fallback={skeleton}>
          <ActivityStreamRenderer component={component} ctx={ctx} />
        </Suspense>
      );

    case 'scatterPlot':
    case 'customMLVisualization':
      // Phase 2 renderers — show a meaningful placeholder with the right visual treatment
      return (
        <ErrorNoticeRenderer
          component={{
            ...component,
            visualizationParameters: {
              errorCode: 'renderer_pending',
              message: `The ${component.type} renderer is scheduled for Phase 2 synthesis. Data has been captured and is available.`,
              severity: 'info',
            },
          }}
          ctx={ctx}
        />
      );

    default:
      return (
        <ErrorNoticeRenderer
          component={{
            ...component,
            visualizationParameters: {
              errorCode: 'unknown_type',
              message: `Unknown component type: ${String(component.type)}`,
            },
          }}
          ctx={ctx}
        />
      );
  }
}
