import { useEffect, useId, useMemo, useState, useRef, type ReactNode } from 'react'
import { CollapsibleCard } from '../basic/collapsible-card'
import { Button } from '../basic/button'
import { FileList2Line } from '../basic/icons-inline'
import { Scrollbar } from '../basic/scrollbar'
import { useMermaidRender } from '../lib/use-mermaid-render'

const ICON_CLASS = 'w-[var(--font-size-sm)] h-[var(--font-size-sm)] shrink-0 text-text-secondary'

export interface MermaidPartProps {
  content?: string
  className?: string
  headerIcon?: ReactNode
  /** 布局风格，与 data-style 一致（如 soft/neutral/sharp），用于图表节点圆角等；不传则从 document 读取 */
  dataStyle?: string
}

const defaultHeaderIcon = <FileList2Line className={ICON_CLASS} />

export function MermaidPart({ content = '', className, headerIcon, dataStyle }: MermaidPartProps) {
  const id = useId()
  const normalized = useMemo(() => (content ?? '').trim(), [content])
  const { svg, error } = useMermaidRender(normalized, id, dataStyle)
  const [scale, setScale] = useState(1)
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!svg || error || !containerRef.current) return
    const el = containerRef.current
    const handleWheel = (e: WheelEvent) => {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault()
        const delta = e.deltaY > 0 ? -0.1 : 0.1
        setScale((prev) => Math.max(0.5, Math.min(3, Math.round((prev + delta) * 10) / 10)))
      }
    }
    el.addEventListener('wheel', handleWheel, { passive: false })
    return () => el.removeEventListener('wheel', handleWheel)
  }, [svg, error])

  const zoomIn = () => setScale((s) => Math.min(3, Math.round((s + 0.1) * 10) / 10))
  const zoomOut = () => setScale((s) => Math.max(0.5, Math.round((s - 0.1) * 10) / 10))
  const reset = () => setScale(1)

  return (
    <CollapsibleCard
      headerIcon={headerIcon ?? defaultHeaderIcon}
      headerTitle={<span className="text-text-secondary">Mermaid</span>}
      headerRight={
        svg && !error ? (
          <div className="flex items-center gap-1" onClick={(e) => e.stopPropagation()}>
            <Button variant="ghost" size="sm" onClick={(e) => { e.stopPropagation(); zoomOut() }} className="shrink-0 px-1.5 py-0.5 text-xs text-text-secondary hover:text-text" aria-label="Zoom out">−</Button>
            <span className="text-xs text-text-secondary min-w-[var(--spacing-10)] text-center">{Math.round(scale * 100)}%</span>
            <Button variant="ghost" size="sm" onClick={(e) => { e.stopPropagation(); reset() }} className="shrink-0 px-1.5 py-0.5 text-xs text-text-secondary hover:text-text" aria-label="Reset">Reset</Button>
            <Button variant="ghost" size="sm" onClick={(e) => { e.stopPropagation(); zoomIn() }} className="shrink-0 px-1.5 py-0.5 text-xs text-text-secondary hover:text-text" aria-label="Zoom in">+</Button>
          </div>
        ) : undefined
      }
      contentPadding="var(--spacing-1\.5) var(--spacing-2)"
      className={className}
    >
      {!normalized ? (
        <div className="text-xs text-text-tertiary">Mermaid content is empty.</div>
      ) : error ? (
        <div className="space-y-2">
          <div className="text-xs text-text-secondary">Mermaid render unavailable.</div>
          <div className="text-xs text-text-tertiary">{error}</div>
          <pre className="m-0 whitespace-pre-wrap break-words font-mono text-xs text-text">{normalized}</pre>
        </div>
      ) : (
        <div className="relative" ref={containerRef}>
          <Scrollbar
            scrollbarVisibility="auto"
            maxHeight={600}
            className="overflow-x-auto"
          >
            <div
              className="flex justify-center items-center"
              style={{ transform: `scale(${scale})`, transformOrigin: 'center top', minHeight: scale > 1 ? '100%' : 'auto' }}
            >
              <div dangerouslySetInnerHTML={{ __html: svg }} />
            </div>
          </Scrollbar>
        </div>
      )}
    </CollapsibleCard>
  )
}

MermaidPart.displayName = 'MermaidPart'
export const MermaidDiagramCard = MermaidPart
export type MermaidDiagramCardProps = MermaidPartProps
