import { useEffect, useRef, useState } from 'react'
import { useContextMenuStore, type ContextMenuIcon } from '@/stores/useContextMenuStore'

function MenuIcon({ icon }: { icon: ContextMenuIcon }) {
  const c = 'currentColor'
  switch (icon) {
    case 'undo':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <polyline points="1 4 1 10 7 10" /><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10" />
        </svg>
      )
    case 'redo':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <polyline points="23 4 23 10 17 10" /><path d="M20.49 15a9 9 0 1 1-2.13-9.36L23 10" />
        </svg>
      )
    case 'cut':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="6" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><line x1="8.12" y1="8.12" x2="15.88" y2="15.88" /><line x1="15.88" y1="8.12" x2="8.12" y2="15.88" />
        </svg>
      )
    case 'copy':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <rect x="9" y="9" width="13" height="13" rx="2" ry="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
        </svg>
      )
    case 'paste':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" /><rect x="8" y="2" width="8" height="4" rx="1" ry="1" />
        </svg>
      )
    case 'selectAll':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <rect x="3" y="3" width="18" height="18" rx="2" ry="2" /><line x1="9" y1="3" x2="9" y2="21" /><line x1="15" y1="3" x2="15" y2="21" /><line x1="3" y1="9" x2="21" y2="9" /><line x1="3" y1="15" x2="21" y2="15" />
        </svg>
      )
    case 'close':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
        </svg>
      )
    case 'rename':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
        </svg>
      )
    case 'trash':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <polyline points="3 6 5 6 21 6" /><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
        </svg>
      )
    case 'folder':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
        </svg>
      )
    case 'file':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14,2 14,8 20,8" />
        </svg>
      )
    case 'link':
      return (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
        </svg>
      )
  }
}

export default function ContextMenu() {
  const isOpen = useContextMenuStore((s) => s.isOpen)
  const x = useContextMenuStore((s) => s.x)
  const y = useContextMenuStore((s) => s.y)
  const items = useContextMenuStore((s) => s.items)
  const close = useContextMenuStore((s) => s.close)

  const menuRef = useRef<HTMLDivElement>(null)
  const [adjustedPos, setAdjustedPos] = useState({ x, y })
  const [selectedIndex, setSelectedIndex] = useState(0)

  const visibleItems = items.filter((i) => !i.separator)
  const totalItems = visibleItems.length

  useEffect(() => {
    if (!isOpen || !menuRef.current) return
    const rect = menuRef.current.getBoundingClientRect()
    const vw = window.innerWidth
    const vh = window.innerHeight
    setAdjustedPos({
      x: x + rect.width > vw ? vw - rect.width - 12 : x,
      y: y + rect.height > vh ? vh - rect.height - 12 : y,
    })
    setSelectedIndex(0)
  }, [isOpen, x, y])

  useEffect(() => {
    if (!isOpen) return
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === 'Escape') { e.preventDefault(); close(); return }
      if (e.key === 'ArrowDown') { e.preventDefault(); setSelectedIndex((i) => Math.min(i + 1, totalItems - 1)); return }
      if (e.key === 'ArrowUp') { e.preventDefault(); setSelectedIndex((i) => Math.max(i - 1, 0)); return }
      if (e.key === 'Enter') {
        e.preventDefault()
        const item = visibleItems[selectedIndex]
        if (item && !item.disabled) { item.action(); close() }
      }
    }
    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [isOpen, selectedIndex, totalItems, visibleItems, close])

  useEffect(() => {
    if (!isOpen || !menuRef.current) return
    function handleClickOutside(e: MouseEvent) {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        close()
      }
    }
    requestAnimationFrame(() => window.addEventListener('mousedown', handleClickOutside))
    return () => window.removeEventListener('mousedown', handleClickOutside)
  }, [isOpen, close])

  if (!isOpen) return null

  return (
    <div
      ref={menuRef}
      className="fixed z-50 min-w-[180px] py-1 rounded-xl shadow-glass overflow-hidden context-menu"
      style={{
        left: adjustedPos.x,
        top: adjustedPos.y,
        backgroundColor: 'var(--color-panel-bg)',
        border: '1px solid var(--color-panel-border)',
      }}
    >
      {items.map((item) => {
        if (item.separator) {
          return (
            <div key={item.id} className="my-1 mx-2" style={{ height: '1px', backgroundColor: 'var(--color-panel-border)' }} />
          )
        }
        const idx = visibleItems.indexOf(item)
        const isSelected = idx === selectedIndex
        return (
          <button
            key={item.id}
            role="menuitem"
            disabled={item.disabled}
            className="w-full flex items-center gap-2.5 px-3 py-1.5 text-ui-sm text-left transition-colors duration-fast disabled:opacity-30 disabled:cursor-default"
            style={{
              backgroundColor: isSelected ? 'var(--color-panel-hover)' : 'transparent',
              color: item.disabled ? 'var(--color-text-muted)' : 'var(--color-text-secondary)',
            }}
            onMouseEnter={() => setSelectedIndex(idx)}
            onClick={() => { if (!item.disabled) { item.action(); close() } }}
          >
            {item.icon && (
              <span className="w-[14px] shrink-0 text-text-muted">
                <MenuIcon icon={item.icon} />
              </span>
            )}
            {!item.icon && <span className="w-[14px] shrink-0" />}
            <span className="flex-1 truncate">{item.label}</span>
            {item.shortcut && (
              <span className="text-ui-xs text-text-muted ml-4">{item.shortcut}</span>
            )}
          </button>
        )
      })}
    </div>
  )
}
