import type { JSXConvertersFunction } from '@payloadcms/richtext-lexical/react'
import type { SerializedLinkNode } from '@payloadcms/richtext-lexical'
import { Button } from '@/components/Button/Button'

// Lexical link nodes carry their editable metadata (url, newTab, linkType, ...)
// in `fields`. We extend that shape with the custom `appearance` select that is
// added to LinkFeature in `payload.config.ts`, so editors can mark a link as a
// call-to-action button.
type LinkFields = SerializedLinkNode['fields'] & {
  appearance?: 'link' | 'button'
}

// Custom JSX converters passed to <RichText /> wherever rich text is rendered.
// Only the `link` converter is overridden — every other node keeps Payload's
// default rendering via the spread of `defaultConverters`.
export const jsxConverters: JSXConvertersFunction = ({ defaultConverters }) => ({
  ...defaultConverters,
  link: (args) => {
    const { node, nodesToJSX } = args
    const fields = node.fields as LinkFields

    // Normal link → delegate to Payload's built-in link converter.
    // The default converter from the package is a function, but the type
    // also allows a static ReactNode, so we narrow before calling.
    if (fields?.appearance !== 'button') {
      const defaultLink = defaultConverters.link
      return typeof defaultLink === 'function' ? defaultLink(args) : defaultLink
    }

    // Button link → resolve href the same way Payload's default converter does:
    // internal links point at the related doc's slug, custom links use `url`.
    const href =
      fields.linkType === 'internal' && typeof fields.doc?.value === 'object'
        ? `/${(fields.doc.value as { slug?: string }).slug ?? ''}`
        : (fields.url ?? '#')

    // Render the existing Button component. Schema and size are intentionally
    // hardcoded — editors only choose link vs. button, not the styling.
    return (
      <Button
        href={href}
        size="md"
        schema="contrast"
        target={fields.newTab ? '_blank' : '_self'}
      >
        {nodesToJSX({ nodes: node.children })}
      </Button>
    )
  },
})
