import { Fragment, useMemo } from 'react'
import type { ReactNode } from 'react'

/**
 * Dil anahtarlarında tutulan düz açıklama metnini okunur bir yapıya çevirir.
 * Metnin kendisi HTML taşımaz; biçim yalnızca aşağıdaki sözleşmeden türetilir,
 * böylece veritabanından gelen içerik sayfaya HTML olarak enjekte edilmez.
 *
 *   - `\n` ile ayrılmış her satır bir blok,
 *   - `• ` ile başlayan ardışık satırlar madde listesi,
 *   - `Etiket: ...` biçimindeki satır başlığı kalın,
 *   - madde içindeki `Ad → açıklama` kalıbında ok öncesi kalın,
 *   - nokta içeren kod benzeri belirteçler ve adresler tek aralıklı rozet.
 */
const CODE_TOKEN = /((?:https?:\/\/\S+)|(?:[A-Za-z][\w-]*(?:\.[\w*-]+)+))/g
const LABEL_LINE = /^([^:]{2,48}):\s+(.*)$/
const BULLET_HEAD = /^(.+?)\s→\s(.*)$/

const withCode = (text: string, keyPrefix: string): ReactNode[] =>
  text.split(CODE_TOKEN).map((part, index) => {
    if (index % 2 === 0) return <Fragment key={`${keyPrefix}-t${index}`}>{part}</Fragment>

    // Cümle sonundaki noktalama rozetin içinde kalmasın.
    const trimmed = part.replace(/[.,;:]+$/, '')

    // "e.g." gibi kısaltmalar kod değildir; rozet yalnızca adres ve tanımlayıcılara.
    if (!/^https?:/.test(trimmed) && !/[A-Z]/.test(trimmed)) {
      return <Fragment key={`${keyPrefix}-p${index}`}>{part}</Fragment>
    }
    const rest = part.slice(trimmed.length)
    return (
      <Fragment key={`${keyPrefix}-c${index}`}>
        <code className="rounded bg-gray-100 px-1 py-0.5 font-mono text-[0.9em] text-gray-800 dark:bg-gray-700 dark:text-gray-100">
          {trimmed}
        </code>
        {rest}
      </Fragment>
    )
  })

const Bullet = ({ text, itemKey }: { text: string; itemKey: string }) => {
  const head = BULLET_HEAD.exec(text)
  if (!head) {
    return <li className="ml-4 list-disc">{withCode(text, itemKey)}</li>
  }

  return (
    <li className="ml-4 list-disc">
      <span className="font-semibold">{head[1]}</span>
      {' → '}
      {withCode(head[2], itemKey)}
    </li>
  )
}

const RichText = ({ text }: { text: string }) => {
  const blocks = useMemo(() => {
    const lines = text.split('\n').filter((line) => line.trim().length > 0)
    const grouped: { type: 'line' | 'list'; items: string[] }[] = []

    lines.forEach((line) => {
      const trimmed = line.trim()
      const isBullet = trimmed.startsWith('•')
      const last = grouped[grouped.length - 1]

      if (isBullet && last?.type === 'list') {
        last.items.push(trimmed.replace(/^•\s*/, ''))
      } else if (isBullet) {
        grouped.push({ type: 'list', items: [trimmed.replace(/^•\s*/, '')] })
      } else {
        grouped.push({ type: 'line', items: [trimmed] })
      }
    })

    return grouped
  }, [text])

  return (
    <div className="flex flex-col gap-2 text-sm leading-relaxed">
      {blocks.map((block, blockIndex) => {
        if (block.type === 'list') {
          return (
            <ul key={`b${blockIndex}`} className="flex flex-col gap-1">
              {block.items.map((item, itemIndex) => (
                <Bullet key={`b${blockIndex}-i${itemIndex}`} itemKey={`b${blockIndex}-i${itemIndex}`} text={item} />
              ))}
            </ul>
          )
        }

        const line = block.items[0]
        const label = LABEL_LINE.exec(line)

        if (blockIndex === 0) {
          return (
            <p key={`b${blockIndex}`} className="text-base font-semibold">
              {withCode(line, `b${blockIndex}`)}
            </p>
          )
        }

        if (!label) {
          return <p key={`b${blockIndex}`}>{withCode(line, `b${blockIndex}`)}</p>
        }

        return (
          <p key={`b${blockIndex}`}>
            <span className="font-semibold">{label[1]}:</span> {withCode(label[2], `b${blockIndex}`)}
          </p>
        )
      })}
    </div>
  )
}

RichText.displayName = 'TooltipRichText'

export default RichText
