// Preview component (SERVER component - runs on server)

import type { ReactNode } from "react";
import React from "react";
import reactElementToJSXString from "react-element-to-jsx-string";
import { getElementDisplayName } from "./getElementDisplayName";
import { PreviewGenerator } from "./PreviewGenerator";

type PreviewProps = React.ComponentProps<typeof PreviewGenerator> & {
  codeJSXOptions?: Record<string, any>;
  children: ReactNode;
};

function generateJSXString(children: ReactNode, options?: Record<string, any>) {
  if (!children) {
    return "";
  }

  if (Array.isArray(children)) {
    return children
      .filter(Boolean) // Filter out null/undefined children
      .map((c) => {
        try {
          // Additional validation for React elements
          if (!React.isValidElement(c)) {
            return "// Invalid React element";
          }
          return reactElementToJSXString(c as any, options);
        } catch (error) {
          console.warn("Failed to generate JSX string for child:", error);
          return "// Unable to generate JSX for this element";
        }
      })
      .join("\n");
  }

  try {
    // Additional validation for React elements
    if (!React.isValidElement(children)) {
      return "// Invalid React element";
    }
    return reactElementToJSXString(children as any, options);
  } catch (error) {
    console.warn("Failed to generate JSX string:", error);
    return "// Unable to generate JSX code";
  }
}

export function Preview({
  children,
  codeJSXOptions,
  codeTypes = ["html", "jsx"],
  ...rest
}: PreviewProps) {
  const normalizedChildren = React.Children.toArray(children);
  const normalizedCode =
    rest.code == null
      ? undefined
      : typeof rest.code === "string" || typeof rest.code === "function"
        ? rest.code
        : React.Children.toArray(rest.code);
  const jsxSource =
    normalizedCode &&
    typeof normalizedCode !== "string" &&
    typeof normalizedCode !== "function"
      ? normalizedCode
      : normalizedChildren;
  const hasMultipleCodeRoots = React.Children.count(jsxSource) > 1;

  // Generate JSX string on server
  const jsxCode = generateJSXString(jsxSource, {
    showDefaultProps: false,
    showFunctions: true,
    functionValue: (fn: any) => fn.name || "Function",
    displayName: getElementDisplayName,
    filterProps: ["mdxType", "originalType"],
    useBooleanShorthandSyntax: false,
    sortProps: false,
    ...codeJSXOptions,
  });

  // Pass the pre-generated JSX code to PreviewGenerator
  return (
    <PreviewGenerator
      {...rest}
      code={normalizedCode}
      hasMultipleCodeRoots={hasMultipleCodeRoots}
      jsxCode={jsxCode}
      codeTypes={codeTypes}
    >
      {normalizedChildren}
    </PreviewGenerator>
  );
}
