import { ReactElement } from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import createElement from "react-syntax-highlighter/dist/esm/create-element";
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { cn } from "@/app/common/utils";
import { capitalizeFirstLetter } from "@/app/common/string-utils";

type CodeHighlighterProps = {
  /**
   * The code to highlight.
   */
  code: string;

  /**
   * The language of the code.
   */
  language?: string;

  /**
   * Should the element be rounded?
   */
  rounded?: boolean;
};

/**
 * Render the rows with the ability to render links.
 *
 * @param rows the rows to render
 * @param stylesheet the stylesheet to use
 * @param useInlineStyles should inline styles be used
 * @returns the rendered rows
 */
function rowRenderer({
  rows,
  stylesheet,
  useInlineStyles,
}: {
  rows: any;
  stylesheet: { [key: string]: React.CSSProperties };
  useInlineStyles: boolean;
}) {
  return rows.map((node: any, i: number) => {
    node.children = node.children.map((children: any) => {
      const text = children?.children?.[0]?.value;

      if (typeof text === "string" && text.startsWith('"http')) {
        return {
          ...children,
          tagName: "a",
          properties: {
            ...children.properties,
            href: text.slice(1, -1), // in JSON strings are enclosed with ", they need to be removed
            target: "_blank",
            // Tailwind CSS classes
            class: "underline !text-primary hover:!text-muted-foreground transition-all",
          },
        };
      }

      return children;
    });

    return createElement({
      node,
      stylesheet,
      useInlineStyles,
      key: `code-segement${i}`,
    });
  });
}

export function CodeHighlighter({ code, language = "json", rounded = true }: CodeHighlighterProps): ReactElement {
  return (
    <div className="text-xs md:text-md relative">
      {/* Language */}
      <div className="absolute top-0 right-0 p-1 bg-muted rounded-bl-md rounded-tr-md">
        <span className="text-xs text-muted-foreground">{capitalizeFirstLetter(language)}</span>
      </div>

      {/* Code */}
      <SyntaxHighlighter
        className={cn("max-h-[600px] !bg-secondary break-all rounded-md", rounded && "rounded-md")}
        language={language}
        style={atomOneDark}
        wrapLongLines
        renderer={rowRenderer}
      >
        {code}
      </SyntaxHighlighter>
    </div>
  );
}
