import React, { ComponentProps } from "react"
import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
import { classNames } from "../../utils"
import { Link } from "../Link"
import { Text } from "../Text"

type Components = NonNullable<
  ComponentProps<typeof ReactMarkdown>["components"]
>

export type MarkdownProps = {
  children: string
  className?: string
  components?: Components
}

const MB_CLASS_NAME = classNames("mb-1.5 last:mb-0 lg:mb-3")

export const Markdown = ({
  children,
  className,
  components,
}: MarkdownProps) => {
  const sharedClassName = classNames("w-fit")
  const baseComponents: Components = {
    a: ({ children, href }) => (
      <Link
        className="whitespace-pre-wrap"
        href={href}
        rel="noopener noreferrer"
        target="_blank"
        variant="default"
      >
        {children}
      </Link>
    ),
    img: () => null,
    iframe: () => null,
    p: props => (
      <Text
        asChild
        className={classNames(
          sharedClassName,
          MB_CLASS_NAME,
          "whitespace-pre-wrap",
        )}
      >
        <p {...props} />
      </Text>
    ),
    span: props => (
      <Text.Body asChild className="whitespace-pre-wrap">
        <span {...props} />
      </Text.Body>
    ),
    li: props => (
      <li
        className={classNames(
          sharedClassName,
          "list-item list-disc whitespace-pre-wrap",
        )}
      >
        <Text.Body asChild size="sm">
          <span {...props} />
        </Text.Body>
      </li>
    ),
    ul: ({ className, ...props }) => (
      <ul
        className={classNames(
          className,
          sharedClassName,
          MB_CLASS_NAME,
          "inline-block list-inside list-disc",
        )}
        {...props}
      />
    ),
    ol: ({ className, ...props }) => (
      <ol
        className={classNames(
          className,
          MB_CLASS_NAME,
          sharedClassName,
          "inline-block list-inside list-decimal",
        )}
        {...props}
      />
    ),
  }
  ;(["h1", "h2", "h3", "h4", "h5", "h6"] as const).forEach(tag => {
    baseComponents[tag] = ({ children }) => (
      <Text.Heading asChild size="sm" style={{ marginBottom: 16 }}>
        <h2>{children}</h2>
      </Text.Heading>
    )
  })

  return (
    <div className={classNames("last:mb-0", className)} data-id="Markdown">
      <ReactMarkdown
        components={{ ...baseComponents, ...components }}
        remarkPlugins={[remarkGfm]}
        skipHtml
      >
        {children}
      </ReactMarkdown>
    </div>
  )
}
