import React, { Fragment, ReactNode } from "react";

export type RichTextChild = {
  type?: string;
  text?: string;
  format?: number;
  children?: RichTextChild[];
};

export type RichTextRoot = {
  root?: {
    children?: RichTextChild[];
  };
};

export function renderLexical(node?: RichTextRoot | RichTextChild | string | null): ReactNode {
  if (!node) return null;

  if (typeof node === "string") {
    return node;
  }

  if ("text" in node && typeof node.text === "string") {
    const format = node.format ?? 0;
    let content: ReactNode = node.text;

    if (format & 1) content = <strong key="bold">{content}</strong>;
    if (format & 2) content = <em key="italic">{content}</em>;
    if (format & 8) content = <u key="underline">{content}</u>;
    if (format & 4) content = <s key="strikethrough">{content}</s>;

    return content;
  }

  const children =
    "root" in node
      ? (node.root?.children ?? [])
      : "children" in node
        ? (node.children ?? [])
        : [];

  if (children.length === 0) return null;

  return (
    <>
      {children.map((child, index) => (
        <Fragment key={index}>
          {renderLexical(child)}
          {child.type === "linebreak" && <br />}
        </Fragment>
      ))}
    </>
  );
}

export function extractPlainText(node?: RichTextRoot | RichTextChild | string | null): string {
  if (!node) return "";

  if (typeof node === "string") {
    return node;
  }

  if (typeof node === "object" && "text" in node && typeof node.text === "string") {
    return node.text;
  }

  const children =
    typeof node === "object" && "root" in node
      ? (node.root?.children ?? [])
      : typeof node === "object" && "children" in node
        ? (node.children ?? [])
        : [];

  return children
    .map((child) => extractPlainText(child))
    .join("");
}
