import { createPortal } from 'react-dom';

import { type RefObject, useEffect, useState, lazy, Suspense } from 'react';

const componentRegistry: Record<
  string,
  React.LazyExoticComponent<React.ComponentType<Record<string, unknown>>>
> = {
  FeatureComparisonMatrix: lazy(() => import('./FeatureComparisonMatrix')),
  CostCalculator: lazy(() => import('./CostCalculator')),
  ChecklistTracker: lazy(() => import('./ChecklistTracker')),
  MetricExplorer: lazy(() => import('./MetricExplorer')),
};

export interface BlogComponentMount {
  id: string;
  name: string;
  props: Record<string, unknown>;
}

interface ComponentMount {
  element: HTMLElement;
  name: string;
  props: Record<string, unknown>;
}

interface BlogComponentInjectorProps {
  contentRef: RefObject<HTMLDivElement | null>;
  components: BlogComponentMount[];
}

export function BlogComponentInjector({ contentRef, components }: BlogComponentInjectorProps) {
  const [mounts, setMounts] = useState<ComponentMount[]>([]);

  useEffect(() => {
    const container = contentRef.current;
    if (!container || components.length === 0) return;

    const newMounts: ComponentMount[] = [];

    components.forEach(({ id, name, props }) => {
      if (!componentRegistry[name]) return;
      const el = container.querySelector<HTMLElement>(`#${CSS.escape(id)}`);
      if (!el) return;
      newMounts.push({ element: el, name, props });
    });

    setMounts(newMounts);
  }, [contentRef, components]);

  return (
    <>
      {mounts.map((mount, i) => {
        const Component = componentRegistry[mount.name];
        if (!Component) return null;

        return createPortal(
          <Suspense
            fallback={
              <div className="flex h-32 items-center justify-center text-sm text-muted-foreground">
                Loading...
              </div>
            }
          >
            <Component {...mount.props} />
          </Suspense>,
          mount.element,
          `blog-component-${mount.name}-${i}`,
        );
      })}
    </>
  );
}
