// components.jsx — shared UI primitives + icons

const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext, Fragment } = React;

// ─────────────────────────────────────────────────────────────
// Icons (inline SVG, stroke-based — friendly weight)
// ─────────────────────────────────────────────────────────────
const Icon = ({ name, size = 20, stroke = 1.7, className = '', style = {} }) => {
  const s = { width: size, height: size, ...style };
  const sw = stroke;
  const paths = {
    home: <><path d="M3 11.5L12 4l9 7.5"/><path d="M5 10v9a1 1 0 001 1h12a1 1 0 001-1v-9"/><path d="M10 20v-5h4v5"/></>,
    receipt: <><path d="M6 3h12v18l-3-2-3 2-3-2-3 2V3z"/><path d="M9 8h6M9 12h6M9 16h3"/></>,
    building: <><rect x="4" y="3" width="16" height="18" rx="1"/><path d="M9 8h.01M15 8h.01M9 12h.01M15 12h.01M9 16h.01M15 16h.01"/></>,
    list: <><path d="M8 6h13M8 12h13M8 18h13"/><circle cx="4" cy="6" r="1"/><circle cx="4" cy="12" r="1"/><circle cx="4" cy="18" r="1"/></>,
    chart: <><path d="M3 3v18h18"/><path d="M7 14l3-3 3 3 5-5"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19 12c0 .5-.1 1-.2 1.5l2.1 1.6-2 3.5-2.5-1c-.8.6-1.6 1-2.5 1.3L13.5 22h-3l-.4-2.1c-.9-.3-1.7-.7-2.5-1.3l-2.5 1-2-3.5 2.1-1.6c-.1-.5-.2-1-.2-1.5s.1-1 .2-1.5l-2.1-1.6 2-3.5 2.5 1c.8-.6 1.6-1 2.5-1.3L10.5 2h3l.4 2.1c.9.3 1.7.7 2.5 1.3l2.5-1 2 3.5-2.1 1.6c.1.5.2 1 .2 1.5z"/></>,
    plus: <><path d="M12 5v14M5 12h14"/></>,
    check: <><path d="M5 12l5 5L20 7"/></>,
    x: <><path d="M6 6l12 12M18 6L6 18"/></>,
    arrowRight: <><path d="M5 12h14M13 5l7 7-7 7"/></>,
    arrowLeft: <><path d="M19 12H5M11 5l-7 7 7 7"/></>,
    bell: <><path d="M18 16v-5a6 6 0 10-12 0v5l-2 2v1h16v-1l-2-2z"/><path d="M10 22a2 2 0 004 0"/></>,
    download: <><path d="M12 4v12M7 11l5 5 5-5"/><path d="M5 20h14"/></>,
    droplet: <><path d="M12 3s-6 7-6 12a6 6 0 0012 0c0-5-6-12-6-12z"/></>,
    flame: <><path d="M12 3c1 4 5 5 5 9a5 5 0 11-10 0c0-2 1-3 2-4 .5 1 1 1.5 2 1.5C11 7 11 5 12 3z"/></>,
    bolt: <><path d="M13 3L4 14h7l-1 7 9-11h-7l1-7z"/></>,
    elevator: <><rect x="5" y="3" width="14" height="18" rx="1"/><path d="M12 3v18M9 8l1.5-2L12 8M12 18l-1.5 2L9 18"/></>,
    sparkles: <><path d="M12 3l2 5 5 2-5 2-2 5-2-5-5-2 5-2 2-5z"/><path d="M19 14l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2zM5 5l.7 1.4L7 7l-1.3.6L5 9l-.7-1.4L3 7l1.3-.6L5 5z"/></>,
    user: <><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-7 8-7s8 3 8 7"/></>,
    phone: <><path d="M5 4h4l2 5-2.5 1.5a11 11 0 005 5L15 13l5 2v4a2 2 0 01-2 2A16 16 0 013 6a2 2 0 012-2z"/></>,
    users: <><circle cx="9" cy="8" r="3.5"/><path d="M3 20c0-3 3-5 6-5s6 2 6 5"/><circle cx="17" cy="9" r="2.5"/><path d="M14 16c.5-.5 2-1.5 3-1.5 2.5 0 4 2 4 4"/></>,
    edit: <><path d="M4 20h4l11-11-4-4L4 16v4z"/></>,
    print: <><path d="M6 9V3h12v6M6 18H4a1 1 0 01-1-1v-7a1 1 0 011-1h16a1 1 0 011 1v7a1 1 0 01-1 1h-2"/><rect x="6" y="14" width="12" height="7" rx="1"/></>,
    mail: <><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></>,
    calc: <><rect x="5" y="3" width="14" height="18" rx="2"/><rect x="8" y="6" width="8" height="3" rx="0.5"/><circle cx="9" cy="13" r="0.7"/><circle cx="12" cy="13" r="0.7"/><circle cx="15" cy="13" r="0.7"/><circle cx="9" cy="17" r="0.7"/><circle cx="12" cy="17" r="0.7"/><circle cx="15" cy="17" r="0.7"/></>,
    clock: <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>,
    grid: <><rect x="4" y="4" width="7" height="7" rx="1"/><rect x="13" y="4" width="7" height="7" rx="1"/><rect x="4" y="13" width="7" height="7" rx="1"/><rect x="13" y="13" width="7" height="7" rx="1"/></>,
    table: <><rect x="3" y="5" width="18" height="14" rx="1"/><path d="M3 10h18M3 15h18M10 5v14M16 5v14"/></>,
    sun: <><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></>,
    moon: <><path d="M21 12.8A9 9 0 0111.2 3a7 7 0 109.8 9.8z"/></>,
    chevDown: <><path d="M6 9l6 6 6-6"/></>,
    chevRight: <><path d="M9 6l6 6-6 6"/></>,
    chevLeft: <><path d="M15 6l-6 6 6 6"/></>,
    search: <><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></>,
    coffee: <><path d="M4 9h13v5a5 5 0 01-10 0V9z"/><path d="M17 11h2a2 2 0 010 4h-2M6 2v3M10 2v3M14 2v3M3 20h17"/></>,
    eye: <><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></>,
    info: <><circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 7v.01"/></>,
    spark: <><path d="M12 2l1.5 6.5L20 10l-6.5 1.5L12 18l-1.5-6.5L4 10l6.5-1.5L12 2z"/></>,
    door: <><path d="M5 21V4a1 1 0 011-1h12a1 1 0 011 1v17M3 21h18M14 12v.01"/></>,
    trash: <><path d="M4 7h16M9 7V4h6v3M6 7l1 13a2 2 0 002 2h6a2 2 0 002-2l1-13"/></>,
    sliders: <><path d="M4 6h8M4 12h2M4 18h12"/><circle cx="16" cy="6" r="2"/><circle cx="10" cy="12" r="2"/><circle cx="20" cy="18" r="2"/></>,
  };
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" style={s} className={className}>
      {paths[name] || null}
    </svg>
  );
};

// ─────────────────────────────────────────────────────────────
// Status badge
// ─────────────────────────────────────────────────────────────
const StatusBadge = ({ status, t, size = 'md' }) => {
  const cfg = {
    paid:     { bg: 'var(--success-bg)',  fg: 'var(--success-fg)',  dot: 'var(--success)',  label: t('status.paid') },
    partial:  { bg: 'var(--warning-bg)',  fg: 'var(--warning-fg)',  dot: 'var(--warning)',  label: t('status.partial') },
    unpaid:   { bg: 'var(--neutral-bg)',  fg: 'var(--neutral-fg)',  dot: 'var(--muted)',    label: t('status.unpaid') },
    overdue:  { bg: 'var(--danger-bg)',   fg: 'var(--danger-fg)',   dot: 'var(--danger)',   label: t('status.overdue') },
    draft:    { bg: 'var(--neutral-bg)',  fg: 'var(--neutral-fg)',  dot: 'var(--muted)',    label: 'Draft' },
    published:{ bg: 'var(--success-bg)',  fg: 'var(--success-fg)',  dot: 'var(--success)',  label: 'Publicat' },
  }[status] || { bg: 'var(--neutral-bg)', fg: 'var(--neutral-fg)', dot: 'var(--muted)', label: status };
  const pad = size === 'sm' ? '3px 8px' : '5px 11px';
  const fs = size === 'sm' ? 11.5 : 12.5;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      background: cfg.bg, color: cfg.fg,
      padding: pad, borderRadius: 999,
      fontSize: fs, fontWeight: 600, letterSpacing: '-0.005em',
      whiteSpace: 'nowrap',
    }}>
      <span style={{ width: 6, height: 6, borderRadius: 999, background: cfg.dot }} />
      {cfg.label}
    </span>
  );
};

// ─────────────────────────────────────────────────────────────
// Button
// ─────────────────────────────────────────────────────────────
const Button = ({ variant = 'primary', size = 'md', icon, children, onClick, type, disabled, style = {}, full = false }) => {
  const sizes = {
    sm: { padding: '7px 12px', fontSize: 13, gap: 6, iconSize: 15 },
    md: { padding: '10px 16px', fontSize: 14, gap: 8, iconSize: 17 },
    lg: { padding: '14px 22px', fontSize: 15.5, gap: 10, iconSize: 19 },
  }[size];
  const variants = {
    primary: { background: 'var(--primary)', color: '#fff', border: '1px solid transparent', boxShadow: '0 1px 0 rgba(255,255,255,0.2) inset, 0 1px 2px rgba(0,0,0,0.08)' },
    secondary: { background: 'var(--surface)', color: 'var(--ink)', border: '1px solid var(--border)' },
    ghost: { background: 'transparent', color: 'var(--ink)', border: '1px solid transparent' },
    danger: { background: 'var(--danger)', color: '#fff', border: '1px solid transparent' },
    success: { background: 'var(--success)', color: '#fff', border: '1px solid transparent' },
  }[variant];
  return (
    <button type={type || 'button'} onClick={onClick} disabled={disabled} style={{
      ...variants, ...sizes,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: sizes.gap,
      width: full ? '100%' : 'auto',
      borderRadius: 10, fontWeight: 600, letterSpacing: '-0.005em',
      cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
      transition: 'transform 120ms ease, background 120ms ease, box-shadow 120ms ease, filter 120ms ease',
      fontFamily: 'inherit',
      ...style,
    }}
    onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.97)'; }}
    onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}
    onMouseLeave={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}
    >
      {icon && <Icon name={icon} size={sizes.iconSize} />}
      {children}
    </button>
  );
};

// ─────────────────────────────────────────────────────────────
// Card
// ─────────────────────────────────────────────────────────────
const Card = ({ children, padded = true, style = {}, onClick }) => (
  <div onClick={onClick} style={{
    background: 'var(--surface)',
    borderRadius: 16,
    border: '1px solid var(--border)',
    boxShadow: '0 1px 2px rgba(28, 22, 12, 0.04), 0 1px 0 rgba(255, 255, 255, 0.6) inset',
    padding: padded ? 'var(--pad-card)' : 0,
    cursor: onClick ? 'pointer' : 'default',
    transition: 'transform 200ms ease, box-shadow 200ms ease',
    ...style,
  }}>
    {children}
  </div>
);

// ─────────────────────────────────────────────────────────────
// Number ticker — animates from 0 to value
// ─────────────────────────────────────────────────────────────
function useTicker(value, duration = 800) {
  const [shown, setShown] = useState(value);
  const startRef = useRef(value);
  const targetRef = useRef(value);
  const tRef = useRef(null);
  useEffect(() => {
    if (value === targetRef.current) return;
    startRef.current = shown;
    targetRef.current = value;
    const t0 = performance.now();
    if (tRef.current) cancelAnimationFrame(tRef.current);
    const tick = (now) => {
      const p = Math.min(1, (now - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setShown(startRef.current + (targetRef.current - startRef.current) * eased);
      if (p < 1) tRef.current = requestAnimationFrame(tick);
    };
    tRef.current = requestAnimationFrame(tick);
    return () => tRef.current && cancelAnimationFrame(tRef.current);
  }, [value]);
  return shown;
}

const Ticker = ({ value, suffix = '', prefix = '', decimals = 0 }) => {
  const v = useTicker(value);
  return <span>{prefix}{v.toLocaleString('ro-RO', { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}{suffix}</span>;
};

// ─────────────────────────────────────────────────────────────
// Modal
// ─────────────────────────────────────────────────────────────
const Modal = ({ open, onClose, title, children, width = 560, footer = null }) => {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, zIndex: 100,
      background: 'rgba(28, 22, 12, 0.45)', backdropFilter: 'blur(6px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24,
      }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        background: 'var(--surface)', borderRadius: 18,
        width: '100%', maxWidth: width, maxHeight: '90vh',
        display: 'flex', flexDirection: 'column',
        boxShadow: '0 24px 60px rgba(28, 22, 12, 0.25), 0 1px 0 rgba(255, 255, 255, 0.8) inset',
        overflow: 'hidden',
      }}>
        {title && (
          <div style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            padding: '20px 24px 16px', borderBottom: '1px solid var(--border)',
          }}>
            <h3 style={{ fontFamily: 'var(--font-display)', fontSize: 19, fontWeight: 600, margin: 0, color: 'var(--ink)' }}>{title}</h3>
            <button onClick={onClose} style={{
              background: 'transparent', border: 0, cursor: 'pointer',
              width: 32, height: 32, borderRadius: 8, color: 'var(--muted)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            }}><Icon name="x" size={18} /></button>
          </div>
        )}
        <div style={{ padding: '20px 24px', overflowY: 'auto', flex: 1 }}>{children}</div>
        {footer && (
          <div style={{ padding: '14px 24px', borderTop: '1px solid var(--border)', background: 'var(--surface-2)' }}>
            {footer}
          </div>
        )}
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Drawer (right side panel)
// ─────────────────────────────────────────────────────────────
const Drawer = ({ open, onClose, title, children, width = 480 }) => {
  if (!open) return null;
  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, zIndex: 90,
      background: 'rgba(28, 22, 12, 0.35)', backdropFilter: 'blur(4px)',
      }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        position: 'absolute', right: 0, top: 0, bottom: 0, width,
        background: 'var(--surface)',
        boxShadow: '-12px 0 40px rgba(28, 22, 12, 0.18)',
        animation: 'slideInRight 260ms cubic-bezier(0.2, 0.9, 0.3, 1)',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '20px 24px', borderBottom: '1px solid var(--border)',
        }}>
          <h3 style={{ fontFamily: 'var(--font-display)', fontSize: 19, fontWeight: 600, margin: 0, color: 'var(--ink)' }}>{title}</h3>
          <button onClick={onClose} style={{
            background: 'transparent', border: 0, cursor: 'pointer',
            width: 32, height: 32, borderRadius: 8, color: 'var(--muted)',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          }}><Icon name="x" size={18} /></button>
        </div>
        <div style={{ overflowY: 'auto', flex: 1, padding: '20px 24px' }}>{children}</div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Toast (sonner-style)
// ─────────────────────────────────────────────────────────────
const ToastContext = createContext(null);
const useToast = () => useContext(ToastContext);
const ToastProvider = ({ children }) => {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg, type = 'success') => {
    const id = Math.random().toString(36).slice(2);
    setToasts(t => [...t, { id, msg, type }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 3500);
  }, []);
  return (
    <ToastContext.Provider value={push}>
      {children}
      <div style={{
        position: 'fixed', bottom: 24, right: 24, zIndex: 200,
        display: 'flex', flexDirection: 'column', gap: 10,
      }}>
        {toasts.map(t => (
          <div key={t.id} style={{
            background: t.type === 'error' ? 'var(--danger)' : 'var(--ink)',
            color: '#fff', padding: '12px 16px', borderRadius: 12,
            boxShadow: '0 8px 24px rgba(28, 22, 12, 0.22)',
            fontSize: 14, fontWeight: 500, maxWidth: 360,
            display: 'flex', alignItems: 'center', gap: 10,
            }}>
            <Icon name={t.type === 'error' ? 'x' : 'check'} size={17} />
            {t.msg}
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
};

// ─────────────────────────────────────────────────────────────
// Striped placeholder for imagery
// ─────────────────────────────────────────────────────────────
const StripedPlaceholder = ({ label, ratio = '4/3', style = {} }) => (
  <div style={{
    aspectRatio: ratio,
    background: 'repeating-linear-gradient(135deg, var(--neutral-bg), var(--neutral-bg) 8px, transparent 8px, transparent 16px), var(--surface-2)',
    border: '1px dashed var(--border)',
    borderRadius: 12,
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    color: 'var(--muted)', fontFamily: 'var(--font-mono)', fontSize: 11,
    ...style,
  }}>{label}</div>
);

// Expose globally
Object.assign(window, {
  Icon, StatusBadge, Button, Card, Modal, Drawer, Ticker, useTicker,
  ToastProvider, useToast, StripedPlaceholder,
});
