import type { JSXConvertersFunction } from '@payloadcms/richtext-lexical/react'
import { LinkJSXConverter } from '@payloadcms/richtext-lexical/react'
import type { SerializedLinkNode } from '@payloadcms/richtext-lexical'
import Image from 'next/image'
import { Button } from '@/components/Button/Button'
import { getPhoto } from '@/utils/dto/gallery'

type LinkFields = SerializedLinkNode['fields'] & {
  appearance?: 'link' | 'button'
}

// Maps an internal Payload document to its public URL based on collection slug.
const internalDocToHref = ({ linkNode }: { linkNode: SerializedLinkNode }): string => {
  const { doc } = linkNode.fields
  if (!doc?.value || typeof doc.value !== 'object') return '#'

  const document = doc.value as Record<string, unknown>

  switch (doc.relationTo) {
    case 'group':
      return `/gruppe/${document.slug ?? document.id}`
    case 'event':
      return `/veranstaltungen/${document.id}`
    case 'worship':
      return `/gottesdienst/${document.id}`
    case 'pages':
      return `/${document.slug ?? ''}`
    case 'parish':
      return `/gemeinde/${document.slug ?? document.id}`
    case 'blog':
      return `/blog/${document.id}`
    default:
      return '#'
  }
}

const linkConverters = LinkJSXConverter({ internalDocToHref })

export const jsxConverters: JSXConvertersFunction = ({ defaultConverters }) => ({
  ...defaultConverters,
  ...linkConverters,
  // Render uploaded media at the "gallery" size (500px tall, variable width).
  upload: ({ node }) => {
    if (node.relationTo !== 'media' || typeof node.value !== 'object') {
      return null
    }

    const photo = getPhoto('gallery', node.value)
    if (!photo) return null

    return (
      <Image
        src={photo.src}
        width={photo.width}
        height={photo.height}
        alt={node.value.alt}
        unoptimized={false}
      />
    )
  },
  link: (args) => {
    const { node, nodesToJSX } = args
    const fields = node.fields as LinkFields

    // Normal link → delegate to the internalDocToHref-aware link converter.
    if (fields?.appearance !== 'button') {
      const linkConverter = linkConverters.link
      return typeof linkConverter === 'function' ? linkConverter(args) : linkConverter
    }

    // Button link → resolve href using internalDocToHref for internal links.
    const href =
      fields.linkType === 'internal'
        ? internalDocToHref({ linkNode: node })
        : (fields.url ?? '#')

    return (
      <Button
        href={href}
        size="md"
        schema="contrast"
        target={fields.newTab ? '_blank' : '_self'}
      >
        {nodesToJSX({ nodes: node.children })}
      </Button>
    )
  },
})
