'use client'

import { useState, useEffect, useCallback } from 'react'
import { Check, Copy } from 'lucide-react'
import { t } from '@/lib/i18n'

// Reuse Shiki highlighter from markdown-renderer
let highlighterPromise: Promise<unknown> | null = null

function getHighlighter() {
  if (!highlighterPromise) {
    highlighterPromise = import('shiki').then(({ createHighlighter }) =>
      createHighlighter({
        themes: ['github-dark', 'github-light'],
        langs: ['json'],
      })
    )
  }
  return highlighterPromise
}

/** Read the current theme from DOM */
function getShikiTheme(): string {
  if (typeof document === 'undefined') return 'github-dark'
  return document.documentElement.getAttribute('data-theme') === 'light' ? 'github-light' : 'github-dark'
}

const SYSTEM_MONO = 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'

/* ── Copy Button ── */

function CopyButton({ text }: { text: string }) {
  const [copied, setCopied] = useState(false)

  const handleCopy = useCallback(async () => {
    await navigator.clipboard.writeText(text)
    setCopied(true)
    setTimeout(() => setCopied(false), 2000)
  }, [text])

  return (
    <button
      onClick={handleCopy}
      className="flex items-center gap-1 px-2 py-1 rounded text-[11px] text-muted hover:text-primary transition-colors"
      title={t('button.copyCode')}
    >
      {copied ? (
        <>
          <Check size={12} className="text-green" />
          <span className="text-green">{t('button.copied')}</span>
        </>
      ) : (
        <>
          <Copy size={12} />
          <span>{t('button.copy')}</span>
        </>
      )}
    </button>
  )
}

interface JsonPreviewProps {
  content: string
}

/**
 * JSON preview with formatting and Shiki syntax highlighting.
 * Falls back to plain text display if content is not valid JSON.
 */
export function JsonPreview({ content }: JsonPreviewProps) {
  const [html, setHtml] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)

  let formatted = content
  try {
    const parsed = JSON.parse(content)
    formatted = JSON.stringify(parsed, null, 2)
  } catch (e) {
    setError(e instanceof Error ? e.message : 'Invalid JSON')
  }

  useEffect(() => {
    let cancelled = false
    getHighlighter().then((hl) => {
      if (cancelled) return
      const highlighter = hl as {
        codeToHtml: (code: string, opts: { lang: string; theme: string }) => string
      }
      try {
        const result = highlighter.codeToHtml(formatted, { lang: 'json', theme: getShikiTheme() })
        setHtml(result)
      } catch {
        setHtml(null)
      }
    }).catch(() => {})
    return () => { cancelled = true }
  }, [formatted])

  return (
    <div className="h-full overflow-y-auto bg-page">
      <div className="my-2 rounded-lg overflow-hidden border border-subtle">
        <div className="flex items-center justify-between px-3 py-1 bg-surface-active border-b border-subtle">
          <div className="flex items-center gap-2">
            <span className="text-[11px] text-muted" style={{ fontFamily: SYSTEM_MONO }}>json</span>
            {error && (
              <span className="text-[11px] text-coral">Parse error — showing raw</span>
            )}
          </div>
          <CopyButton text={formatted} />
        </div>
        {html ? (
          <div
            className="text-[12px] overflow-x-auto [&_pre]:!m-0 [&_pre]:!p-3 [&_code]:!bg-transparent"
            style={{ fontFamily: SYSTEM_MONO }}
            dangerouslySetInnerHTML={{ __html: html }}
          />
        ) : (
          <pre className="px-3 py-2 bg-elevated text-[12px] text-primary overflow-x-auto" style={{ fontFamily: SYSTEM_MONO }}>
            <code>{formatted}</code>
          </pre>
        )}
      </div>
    </div>
  )
}
