// Minimal Lexical → React renderer. Only handles the node kinds our CMS
// emits today (heading h1-h4, paragraph, list/listitem, link, text,
// linebreak). Add cases as new node kinds appear.

import type { JSX } from "react";
import type { LexNode, LexRoot } from "@/lib/cms";

function renderNodes(nodes: LexNode[] | undefined): JSX.Element[] {
	return (nodes ?? []).map((n, i) => renderNode(n, i));
}

function renderNode(n: LexNode, key: number): JSX.Element {
	switch (n.type) {
		case "text": {
			const format = (n as { format?: number }).format ?? 0;
			let el: JSX.Element = <>{n.text}</>;
			if (format & 1) el = <strong>{el}</strong>;
			if (format & 2) el = <em>{el}</em>;
			if (format & 8) el = <u>{el}</u>;
			if (format & 16) el = <code>{el}</code>;
			return <span key={key}>{el}</span>;
		}

		case "linebreak":
			return <br key={key} />;

		case "paragraph":
			return <p key={key}>{renderNodes(n.children)}</p>;

		case "heading": {
			const Tag = (n.tag ?? "h2") as keyof JSX.IntrinsicElements;
			return <Tag key={key}>{renderNodes(n.children)}</Tag>;
		}

		case "list": {
			const Tag = (n.tag === "ol" ? "ol" : "ul") as "ol" | "ul";
			return <Tag key={key}>{renderNodes(n.children)}</Tag>;
		}

		case "listitem":
			return <li key={key}>{renderNodes(n.children)}</li>;

		case "link": {
			const url = n.fields?.url ?? "#";
			const newTab = Boolean(n.fields?.newTab);
			return (
				<a
					key={key}
					href={url}
					{...(newTab
						? { target: "_blank", rel: "noopener noreferrer" }
						: {})}
				>
					{renderNodes(n.children)}
				</a>
			);
		}

		default:
			return <span key={key} />;
	}
}

export default function RichText({ data }: { data: LexRoot | null | undefined }) {
	if (!data?.root) return null;
	return <>{renderNodes(data.root.children)}</>;
}
