import { useRef, useState } from 'react'
import useThemeStore from '../store/themeStore'
import useTableColourStore from '../store/tableColourStore'

const API_URL = import.meta.env.VITE_API_URL || ''

const STATUS_LABELS = {
  free:           'ΕΛΕΥΘΕΡΟ',
  open:           'ΑΝΟΙΧΤΟ',
  mine:           'ΔΙΚΟ ΜΟΥ',
  paid:           'ΠΛΗΡΩΜΕΝΟ',
  partially_paid: 'ΜΕΡ. ΠΛHΡ.',
}

const DRAG_THRESHOLD = 8
const HOLD_MS = 480

// ─── Avatar helpers ───────────────────────────────────────────────────────────

const AVATAR_PALETTE = ['#3758c9', '#7a44c9', '#2f9e5e', '#d94b26', '#8a6d2b', '#0d7a8a', '#c93775', '#1d6f3a']

function avatarColor(name = '') {
  let h = 0
  for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0
  return AVATAR_PALETTE[h % AVATAR_PALETTE.length]
}

function WaiterAvatar({ waiter, size = 22, ring }) {
  const displayName = waiter.nickname || waiter.full_name || waiter.username || '?'
  const initials = displayName.trim().split(' ').map(p => p[0]).slice(0, 2).join('').toUpperCase()
  const ringStyle = ring ? { boxShadow: `0 0 0 2px ${ring}` } : {}

  if (waiter.avatar_url) {
    return (
      <img
        src={API_URL + waiter.avatar_url}
        alt={displayName}
        style={{
          width: size, height: size, borderRadius: '50%',
          objectFit: 'cover', flexShrink: 0,
          ...ringStyle,
        }}
      />
    )
  }
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: avatarColor(displayName),
      color: 'white', fontSize: size * 0.4, fontWeight: 700,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
      ...ringStyle,
    }}>{initials}</div>
  )
}

// Renders [icon] Name, [icon] Name inline. Falls back to icons + "X Waiters" if they don't fit
// (we approximate "don't fit" as > 2 waiters for the compact footer height).
function WaiterRow({ waiters, size = 22, cfg }) {
  if (!waiters?.length) return null
  const textColor = cfg.nameText

  // ≤ 2 waiters: show icon + name pairs
  if (waiters.length <= 2) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'nowrap', overflow: 'hidden', minWidth: 0 }}>
        {waiters.map((w, i) => {
          const name = w.nickname || w.full_name || w.username || '?'
          return (
            <div key={w.id} style={{ display: 'flex', alignItems: 'center', gap: 5, minWidth: 0, overflow: 'hidden' }}>
              {i > 0 && <span style={{ color: textColor, opacity: 0.3, fontSize: 14, flexShrink: 0 }}>·</span>}
              <WaiterAvatar waiter={w} size={size} />
              <span style={{
                fontSize: 12, fontWeight: 600, color: textColor, opacity: 0.85,
                overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
              }}>{name}</span>
            </div>
          )
        })}
      </div>
    )
  }

  // > 2 waiters: icons only + "X Waiters" label
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
      {waiters.slice(0, 3).map((w, i) => (
        <div key={w.id} style={{ marginLeft: i === 0 ? 0 : -(size * 0.28) }}>
          <WaiterAvatar waiter={w} size={size} ring={cfg.cardBg} />
        </div>
      ))}
      {waiters.length > 3 && (
        <div style={{
          marginLeft: -(size * 0.28), height: size, padding: '0 6px',
          borderRadius: size, background: `${cfg.nameText}20`,
          color: cfg.nameText, fontSize: 10, fontWeight: 700,
          display: 'flex', alignItems: 'center',
        }}>+{waiters.length - 3}</div>
      )}
      <span style={{ fontSize: 12, fontWeight: 600, color: textColor, opacity: 0.7, marginLeft: 4 }}>
        {waiters.length} σερβιτόροι
      </span>
    </div>
  )
}

// ─── Status pill ──────────────────────────────────────────────────────────────

function StatusPill({ label, badgeBg, badgeText, small }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center',
      height: small ? 18 : 20,
      padding: small ? '0 6px' : '0 8px',
      borderRadius: 4,
      background: badgeBg,
      color: badgeText,
      fontSize: small ? 9 : 10,
      fontWeight: 800,
      letterSpacing: 0.4,
      whiteSpace: 'nowrap',
    }}>{label}</span>
  )
}

// ─── Flag dot ─────────────────────────────────────────────────────────────────

function FlagDot({ flag, size = 22 }) {
  const textColor = flag.text_color || '#ffffff'
  return (
    <div
      title={flag.name}
      style={{
        width: size, height: size, borderRadius: '50%',
        background: flag.color || '#6295F3',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: size * 0.55,
        flexShrink: 0,
        color: textColor,
      }}
    >
      {flag.emoji || '🏷️'}
    </div>
  )
}

// ─── Flag overflow row: show up to maxShow dots, then +N bubble ───────────────

function FlagDots({ flags, size, maxShow }) {
  if (!flags.length) return null
  const visible = flags.slice(0, maxShow)
  const overflow = flags.length - maxShow
  return (
    <div style={{ display: 'flex', gap: 3, alignItems: 'center' }}>
      {visible.map(f => <FlagDot key={f.id} flag={f} size={size} />)}
      {overflow > 0 && (
        <div style={{
          width: size, height: size, borderRadius: '50%',
          background: 'rgba(0,0,0,0.18)',
          color: '#fff', fontSize: size * 0.44, fontWeight: 800,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>+{overflow}</div>
      )}
    </div>
  )
}

// ─── Flag chip (icon + label) ─────────────────────────────────────────────────

function FlagChip({ flag }) {
  const textColor = flag.text_color || '#ffffff'
  return (
    <div
      title={flag.name}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 5,
        height: 26, padding: '0 9px',
        borderRadius: 13,
        background: flag.color || '#6295F3',
        flexShrink: 0,
      }}
    >
      <span style={{ fontSize: 13, lineHeight: 1 }}>{flag.emoji || '🏷️'}</span>
      <span style={{ fontSize: 11, fontWeight: 700, color: textColor, whiteSpace: 'nowrap' }}>
        {flag.name}
      </span>
    </div>
  )
}

// ─── Amount display ───────────────────────────────────────────────────────────

function Amount({ value, size = 22, color }) {
  const s = Number(value || 0).toFixed(2)
  const [whole, cents] = s.split('.')
  const isNum = typeof size === 'number'
  const centsSize = isNum ? size * 0.56 : `calc(${size} * 0.56)`
  return (
    <div style={{ lineHeight: 1, color: color || 'inherit' }}>
      <span style={{ fontSize: size, fontWeight: 800, letterSpacing: -0.5 }}>{whole}</span>
      <span style={{ fontSize: centsSize, fontWeight: 800, opacity: 0.8 }}>.{cents}€</span>
    </div>
  )
}

// ─── Card variants ────────────────────────────────────────────────────────────

// 1x1 — square-ish, 4 per row. Badges top (up to 2 + +N), name center, status bottom.
function Card1x1({ table, order, flags, waiterObjects, cfg, statusKey }) {
  return (
    <div style={{
      width: '100%', aspectRatio: '1 / 1.05',
      background: cfg.cardBg, borderRadius: 14,
      position: 'relative', overflow: 'hidden',
      display: 'flex', flexDirection: 'column',
      padding: 8,
      boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
    }}>
      {/* top strip: badges up to 2, then +N */}
      <div style={{ height: '20%', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 3 }}>
        <FlagDots flags={flags} size={16} maxShow={2} />
      </div>

      {/* center: name */}
      <div style={{
        flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontWeight: 800, fontSize: 'clamp(18px, 5vw, 26px)',
        letterSpacing: -0.5, color: cfg.nameText, lineHeight: 1,
      }}>
        {table.label || `T${table.number}`}
      </div>

      {/* bottom strip: status */}
      <div style={{ height: '20%', display: 'flex', alignItems: 'flex-end', justifyContent: 'center' }}>
        <span style={{
          fontSize: 7, fontWeight: 800, letterSpacing: 0.3,
          color: cfg.badgeText, textTransform: 'uppercase',
          background: cfg.badgeBg, borderRadius: 3,
          padding: '1px 4px', whiteSpace: 'nowrap',
        }}>
          {STATUS_LABELS[statusKey]}
        </span>
      </div>
    </div>
  )
}

// 2x1 — half width, compact horizontal. Name left, status + badges (up to 3 + +N) right.
function Card2x1({ table, order, flags, waiterObjects, cfg, statusKey }) {
  return (
    <div style={{
      width: '100%', height: 64,
      background: cfg.cardBg, borderRadius: 14,
      padding: '10px 12px',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      gap: 10, overflow: 'hidden',
      boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
    }}>
      <div style={{
        fontWeight: 800, fontSize: 'clamp(18px, 4.5vw, 24px)',
        letterSpacing: -0.5, color: cfg.nameText, lineHeight: 1, flexShrink: 0,
      }}>
        {table.label || `T${table.number}`}
      </div>

      <div style={{
        display: 'flex', flexDirection: 'column',
        alignItems: 'flex-end', justifyContent: 'center', gap: 4,
      }}>
        <StatusPill label={STATUS_LABELS[statusKey]} badgeBg={cfg.badgeBg} badgeText={cfg.badgeText} small />
        {flags.length > 0 && (
          <FlagDots flags={flags} size={18} maxShow={3} />
        )}
      </div>
    </div>
  )
}

// 2x2 — current-style square. Name top-left, status (slightly smaller) below, amount bottom-left, flags right.
function Card2x2({ table, order, flags, waiterObjects, cfg, statusKey }) {
  const isFree = !order
  const total = order?.items?.filter(i => i.status === 'active').reduce((s, i) => s + i.unit_price * i.quantity, 0) ?? 0
  const showAmount = !isFree

  return (
    <div style={{
      width: '100%', minHeight: 116,
      background: cfg.cardBg, borderRadius: 16,
      padding: '12px 12px 12px',
      display: 'flex', gap: 8, overflow: 'hidden',
      boxShadow: '0 2px 10px rgba(0,0,0,0.12)',
    }}>
      {/* left column */}
      <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
        <span style={{
          fontSize: 'clamp(22px, 5.5vw, 36px)', fontWeight: 800,
          lineHeight: 1.05, color: cfg.nameText, letterSpacing: -0.5,
        }}>
          {table.label || `T${table.number}`}
        </span>
        <div style={{ marginTop: 5 }}>
          <StatusPill label={STATUS_LABELS[statusKey]} badgeBg={cfg.badgeBg} badgeText={cfg.badgeText} small />
        </div>
        <div style={{ marginTop: 'auto', paddingTop: 8, minHeight: 28 }}>
          {showAmount && <Amount value={total} size={'clamp(22px, 5.5vw, 36px)'} color={cfg.nameText} />}
        </div>
      </div>

      {/* right column: flags — show 2, then +N */}
      {flags.length > 0 && (
        <div style={{
          display: 'flex', flexDirection: 'column-reverse',
          gap: 4, alignItems: 'flex-end', justifyContent: 'flex-start',
        }}>
          <FlagDots flags={flags} size={26} maxShow={2} />
        </div>
      )}
    </div>
  )
}

// 4x1 — full width horizontal. Name + amount left-center, badges (up to 3 + +N) + status right.
function Card4x1({ table, order, flags, waiterObjects, cfg, statusKey }) {
  const isFree = !order
  const total = order?.items?.filter(i => i.status === 'active').reduce((s, i) => s + i.unit_price * i.quantity, 0) ?? 0
  const showAmount = !isFree

  return (
    <div style={{
      width: '100%', height: 68,
      background: cfg.cardBg, borderRadius: 14,
      padding: '12px 14px',
      display: 'flex', alignItems: 'center', gap: 14, overflow: 'hidden',
      boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
    }}>
      {/* name */}
      <div style={{
        fontWeight: 800, fontSize: 'clamp(20px, 4.5vw, 28px)',
        letterSpacing: -0.5, color: cfg.nameText, lineHeight: 1, flexShrink: 0,
      }}>
        {table.label || `T${table.number}`}
      </div>

      {/* separator dot */}
      <span style={{ color: cfg.nameText, opacity: 0.3, fontSize: 20, lineHeight: 1, flexShrink: 0 }}>·</span>

      {/* amount */}
      <div style={{ flex: 1, display: 'flex', alignItems: 'center' }}>
        {showAmount && <Amount value={total} size={'clamp(20px, 4.5vw, 28px)'} color={cfg.nameText} />}
      </div>

      {/* flags up to 3 + +N */}
      {flags.length > 0 && (
        <FlagDots flags={flags} size={24} maxShow={3} />
      )}

      {/* status */}
      <StatusPill label={STATUS_LABELS[statusKey]} badgeBg={cfg.badgeBg} badgeText={cfg.badgeText} />
    </div>
  )
}

// 4x2 — full width, tall. One main row: name+zone left, status center, amount+flags right. Flag chips below. Waiter footer.
function Card4x2({ table, order, flags, waiterObjects, groupName, cfg, statusKey }) {
  const isFree = !order
  const total = order?.items?.filter(i => i.status === 'active').reduce((s, i) => s + i.unit_price * i.quantity, 0) ?? 0
  const showAmount = !isFree
  const showWaiters = !isFree && waiterObjects.length > 0

  return (
    <div style={{
      width: '100%',
      background: cfg.cardBg, borderRadius: 16,
      overflow: 'hidden',
      boxShadow: '0 2px 10px rgba(0,0,0,0.12)',
      display: 'flex', flexDirection: 'column',
    }}>
      {/* main body */}
      <div style={{ padding: '14px 14px 12px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {/* top row: name LEFT | status CENTER | amount RIGHT — all top-aligned */}
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
          {/* left: name + zone */}
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{
              fontWeight: 800, fontSize: 'clamp(30px, 7vw, 44px)',
              letterSpacing: -1.5, lineHeight: 1, color: cfg.nameText,
            }}>
              {table.label || `T${table.number}`}
            </div>
            {groupName && (
              <div style={{
                fontSize: 10, fontWeight: 700, letterSpacing: 0.8,
                color: cfg.nameText, opacity: 0.6,
                textTransform: 'uppercase', marginTop: 3,
              }}>
                {groupName}
              </div>
            )}
          </div>

          {/* center: status pill — top-aligned via paddingTop to optically align with name cap */}
          <div style={{ paddingTop: 4, flexShrink: 0 }}>
            <StatusPill label={STATUS_LABELS[statusKey]} badgeBg={cfg.badgeBg} badgeText={cfg.badgeText} />
          </div>

          {/* right: amount — top-aligned */}
          {showAmount && (
            <div style={{ flexShrink: 0 }}>
              <Amount value={total} size={'clamp(30px, 7vw, 44px)'} color={cfg.nameText} />
            </div>
          )}
        </div>

        {/* flag chips row — right-aligned */}
        {flags.length > 0 && (
          <div style={{ display: 'flex', justifyContent: 'flex-end', flexWrap: 'wrap', gap: 6 }}>
            {flags.slice(0, 4).map(f => <FlagChip key={f.id} flag={f} />)}
            {flags.length > 4 && (
              <div style={{
                height: 26, padding: '0 9px', borderRadius: 13,
                background: 'rgba(0,0,0,0.18)', color: '#fff',
                fontSize: 11, fontWeight: 800,
                display: 'flex', alignItems: 'center',
              }}>+{flags.length - 4}</div>
            )}
          </div>
        )}
      </div>

      {/* footer: waiters */}
      <div style={{
        borderTop: `1px solid ${cfg.nameText}22`,
        padding: '10px 14px', minHeight: 40,
        display: 'flex', alignItems: 'center',
      }}>
        {showWaiters
          ? <WaiterRow waiters={waiterObjects} size={24} cfg={cfg} />
          : <span style={{ fontSize: 12, color: cfg.nameText, opacity: 0.45 }}>—</span>
        }
      </div>
    </div>
  )
}

// 4x3 — full width, two-column detail card. Left: name/zone/status/amount. Right: order items list. Footer: waiters.
function Card4x3({ table, order, flags, waiterObjects, groupName, cfg, statusKey }) {
  const isFree = !order
  const activeItems = order?.items?.filter(i => i.status === 'active') ?? []
  const total = activeItems.reduce((s, i) => s + i.unit_price * i.quantity, 0)
  const showWaiters = !isFree && waiterObjects.length > 0

  return (
    <div style={{
      width: '100%',
      background: cfg.cardBg, borderRadius: 16,
      overflow: 'hidden',
      boxShadow: '0 2px 10px rgba(0,0,0,0.12)',
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{ display: 'flex', padding: '14px 14px 10px', gap: 14, minWidth: 0, overflow: 'hidden' }}>
        {/* left column: name, zone, amount, status, flags */}
        <div style={{ display: 'flex', flexDirection: 'column', minWidth: 100, flexShrink: 0, justifyContent: 'space-between' }}>
          <div>
            <div style={{
              fontWeight: 800, fontSize: 'clamp(28px, 6vw, 40px)',
              letterSpacing: -1.5, lineHeight: 1, color: cfg.nameText,
            }}>
              {table.label || `T${table.number}`}
            </div>
            {groupName && (
              <div style={{
                fontSize: 10, fontWeight: 700, letterSpacing: 0.8,
                color: cfg.nameText, opacity: 0.6,
                textTransform: 'uppercase', marginTop: 3,
              }}>
                {groupName}
              </div>
            )}
          </div>

          <div style={{ marginTop: 10 }}>
            {!isFree && <Amount value={total} size={'clamp(22px, 5vw, 32px)'} color={cfg.nameText} />}
          </div>

          <div style={{ marginTop: 8 }}>
            <StatusPill label={STATUS_LABELS[statusKey]} badgeBg={cfg.badgeBg} badgeText={cfg.badgeText} small />
          </div>

          {flags.length > 0 && (
            <div style={{ marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 4 }}>
              <FlagDots flags={flags} size={22} maxShow={3} />
            </div>
          )}
        </div>

        {/* divider */}
        <div style={{ width: 1, background: `${cfg.nameText}20`, alignSelf: 'stretch', flexShrink: 0 }} />

        {/* right column: order items */}
        <div style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>
          {isFree ? (
            <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <span style={{ fontSize: 12, color: cfg.nameText, opacity: 0.35 }}>Ελεύθερο</span>
            </div>
          ) : activeItems.length === 0 ? (
            <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <span style={{ fontSize: 12, color: cfg.nameText, opacity: 0.35 }}>Κανένα είδος</span>
            </div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 3, minWidth: 0 }}>
              {activeItems.slice(0, 7).map(item => (
                <div key={item.id} style={{ display: 'flex', alignItems: 'baseline', gap: 5, overflow: 'hidden', minWidth: 0 }}>
                  <span style={{
                    fontSize: 11, fontWeight: 700, color: cfg.nameText,
                    background: `${cfg.nameText}18`, borderRadius: 3,
                    padding: '1px 5px', flexShrink: 0,
                  }}>{item.quantity}×</span>
                  <span style={{
                    fontSize: 12, fontWeight: 500, color: cfg.nameText,
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1,
                  }}>{item.product?.name || `#${item.product_id}`}</span>
                  <span style={{ fontSize: 11, fontWeight: 700, color: cfg.nameText, opacity: 0.7, flexShrink: 0 }}>
                    {(item.unit_price * item.quantity).toFixed(2)}€
                  </span>
                </div>
              ))}
              {activeItems.length > 7 && (
                <div style={{ fontSize: 11, color: cfg.nameText, opacity: 0.5, marginTop: 2 }}>
                  +{activeItems.length - 7} ακόμα…
                </div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* footer: waiters */}
      <div style={{
        borderTop: `1px solid ${cfg.nameText}22`,
        padding: '10px 14px', minHeight: 38,
        display: 'flex', alignItems: 'center',
      }}>
        {showWaiters
          ? <WaiterRow waiters={waiterObjects} size={22} cfg={cfg} />
          : <span style={{ fontSize: 12, color: cfg.nameText, opacity: 0.45 }}>—</span>
        }
      </div>
    </div>
  )
}

// ─── Main export ──────────────────────────────────────────────────────────────

export default function TableCard({
  table,
  order,
  isMine,
  flags = [],
  groupName = '',
  waiterObjects = [],
  density = '2x2',
  onClick,
  onLongPress,
}) {
  const holdTimer   = useRef(null)
  const startPos    = useRef({ x: 0, y: 0 })
  const didFire     = useRef(false)
  const [showTip, setShowTip] = useState(false)

  const dark    = useThemeStore(s => s.dark)
  const colours = useTableColourStore(s => s.colours)

  let statusKey = 'free'
  if (order?.status === 'paid')                statusKey = 'paid'
  else if (order?.status === 'partially_paid') statusKey = 'partially_paid'
  else if (order && isMine)                    statusKey = 'mine'
  else if (order)                              statusKey = 'open'

  const mode = dark ? 'dark' : 'light'
  const cfg  = colours[mode][statusKey]

  function cancel() {
    clearTimeout(holdTimer.current)
    holdTimer.current = null
  }

  function onTouchStart(e) {
    const t = e.touches[0]
    startPos.current = { x: t.clientX, y: t.clientY }
    didFire.current = false
    holdTimer.current = setTimeout(() => {
      didFire.current = true
      if (onLongPress) onLongPress()
      else setShowTip(true)
    }, HOLD_MS)
  }

  function onTouchMove(e) {
    if (!holdTimer.current) return
    const t = e.touches[0]
    const dx = Math.abs(t.clientX - startPos.current.x)
    const dy = Math.abs(t.clientY - startPos.current.y)
    if (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD) cancel()
  }

  function onTouchEnd() { cancel(); setShowTip(false) }

  function onMouseDown(e) {
    startPos.current = { x: e.clientX, y: e.clientY }
    didFire.current = false
    holdTimer.current = setTimeout(() => {
      didFire.current = true
      if (onLongPress) onLongPress()
      else setShowTip(true)
    }, HOLD_MS)
  }
  function onMouseMove(e) {
    if (!holdTimer.current) return
    const dx = Math.abs(e.clientX - startPos.current.x)
    const dy = Math.abs(e.clientY - startPos.current.y)
    if (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD) cancel()
  }
  function onMouseUp()    { cancel(); setShowTip(false) }
  function onMouseLeave() { cancel(); setShowTip(false) }

  function handleClick(e) {
    if (didFire.current) { e.preventDefault(); return }
    onClick?.()
  }

  const cardProps = { table, order, flags, waiterObjects, groupName, cfg, statusKey }

  const CardComponent = {
    '1x1': Card1x1,
    '2x1': Card2x1,
    '2x2': Card2x2,
    '4x1': Card4x1,
    '4x2': Card4x2,
    '4x3': Card4x3,
  }[density] || Card2x2

  return (
    <div style={{ position: 'relative', minWidth: 0, overflow: 'hidden' }}>
      <button
        style={{ display: 'block', width: '100%', background: 'none', border: 'none', padding: 0, cursor: 'pointer', textAlign: 'left' }}
        onClick={handleClick}
        onTouchStart={onTouchStart}
        onTouchMove={onTouchMove}
        onTouchEnd={onTouchEnd}
        onMouseDown={onMouseDown}
        onMouseMove={onMouseMove}
        onMouseUp={onMouseUp}
        onMouseLeave={onMouseLeave}
      >
        <CardComponent {...cardProps} />
      </button>

      {showTip && flags.length > 0 && (
        <div style={{
          position: 'absolute', bottom: 'calc(100% + 8px)', right: 0,
          background: 'var(--bg2)', border: '1px solid var(--border)',
          borderRadius: 10, padding: '8px 12px', zIndex: 50,
          boxShadow: '0 4px 16px var(--shadow)',
          minWidth: 160, pointerEvents: 'none',
        }}>
          {flags.map(f => (
            <div key={f.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0' }}>
              <span style={{ fontSize: 15 }}>{f.emoji || '🏷️'}</span>
              <span style={{ fontSize: 13, color: 'var(--text)' }}>{f.name}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  )
}
