import React from 'react'
import MessageFormatted from './MessageFormatted'
import type { MessageFormatPart } from './chatUtils'

/**
 * Map §-format color codes to Minecraft named colors.
 * Supports color codes (§0-§9, §a-§f) and formatting (§l, §o, §n, §m, §k, §r).
 */
const CODE_COLORS: Record<string, string> = {
  '0': 'black',      '1': 'dark_blue',   '2': 'dark_green', '3': 'dark_aqua',
  '4': 'dark_red',   '5': 'dark_purple', '6': 'gold',       '7': 'gray',
  '8': 'dark_gray',  '9': 'blue',        'a': 'green',      'b': 'aqua',
  'c': 'red',        'd': 'light_purple','e': 'yellow',     'f': 'white',
}

function parseSectionCodes(text: string): MessageFormatPart[] {
  const parts: MessageFormatPart[] = []
  const regex = /§([0-9a-fk-orA-FK-OR])|([^§]+)/g
  regex.lastIndex = 0
  let color: string | undefined
  let bold = false, italic = false, underlined = false
  let strikethrough = false, obfuscated = false
  let match: RegExpExecArray | null
  while ((match = regex.exec(text)) !== null) {
    const code = match[1]?.toLowerCase()
    const chunk = match[2]
    if (code !== undefined) {
      if (CODE_COLORS[code]) {
        color = CODE_COLORS[code]
        bold = italic = underlined = strikethrough = obfuscated = false
      } else if (code === 'l') bold = true
      else if (code === 'o') italic = true
      else if (code === 'n') underlined = true
      else if (code === 'm') strikethrough = true
      else if (code === 'k') obfuscated = true
      else if (code === 'r') {
        color = undefined
        bold = italic = underlined = strikethrough = obfuscated = false
      }
    } else if (chunk) {
      parts.push({ text: chunk, color, bold, italic, underlined, strikethrough, obfuscated })
    }
  }
  return parts
}

interface Props {
  text: string | undefined | null
  className?: string
  /** Wrap in a specific element; defaults to the MessageFormatted span wrapper */
  fallbackColor?: string
}

/**
 * Renders a Minecraft text string that may contain §-formatting codes.
 * For plain strings without §, renders as a simple <span>.
 * Used for inventory titles, tooltip names, and lore lines.
 */
export function MessageFormattedString({ text, className, fallbackColor }: Props) {
  if (!text) return null

  if (!text.includes('§')) {
    return (
      <span
        className={className}
        style={fallbackColor ? { color: fallbackColor } : undefined}
      >
        {text}
      </span>
    )
  }

  const parts = parseSectionCodes(text)
  return <MessageFormatted parts={parts} className={className} />
}
