/**
 * YBP Design System — Shared Components
 * EmptyState · ErrorState · LoadingSkeleton · Toast · ConfirmDialog
 *
 * שימוש:
 *   <EmptyState icon="folder" title="אין פרויקטים" description="..." primaryAction={{label,onClick}} />
 *   <ErrorState type="network" onRetry={fn} />
 *   <LoadingSkeleton type="cards" count={6} />
 *   toastSuccess('נשמר!') / toastError('שגיאה') / toastInfo('...')
 *   <ConfirmDialog isOpen title="מחוק?" confirmLabel="מחק" onConfirm={fn} onCancel={fn} />
 */

// ─────────────────────────────────────────────────────────────────────────────
// Design Tokens
// ─────────────────────────────────────────────────────────────────────────────
const DS = {
  navy:    '#1a2c4a',
  gold:    '#b5a882',
  beige:   '#c8bfa8',
  green:   '#16a34a',
  yellow:  '#eab308',
  red:     '#dc2626',
  blue:    '#2563eb',
  gray:    '#6b7280',
  font:    "'Assistant', sans-serif",
};

// ─────────────────────────────────────────────────────────────────────────────
// SVG Icons (minimal — only what's needed here)
// ─────────────────────────────────────────────────────────────────────────────
const DSIcon = ({ name, size = 40, color = DS.gray }) => {
  const icons = {
    folder:       <><path d="M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2V7z" stroke={color} strokeWidth="1.5" fill="none"/></>,
    wifi_off:     <><line x1="1" y1="1" x2="23" y2="23" stroke={color} strokeWidth="1.5"/><path d="M16.72 11.06A11 11 0 0119 12.55M5 12.55a11 11 0 015.17-2.39M10.71 5.05A16 16 0 0122.56 9M1.42 9a16 16 0 014.42-2.84M8.53 16.11a6 6 0 016.95 0M12 20h.01" stroke={color} strokeWidth="1.5" fill="none"/></>,
    lock:         <><rect x="3" y="11" width="18" height="11" rx="2" ry="2" stroke={color} strokeWidth="1.5" fill="none"/><path d="M7 11V7a5 5 0 0110 0v4" stroke={color} strokeWidth="1.5" fill="none"/></>,
    compass:      <><circle cx="12" cy="12" r="10" stroke={color} strokeWidth="1.5" fill="none"/><polygon points="16.24,7.76 14.12,14.12 7.76,16.24 9.88,9.88" stroke={color} strokeWidth="1.5" fill="none"/></>,
    server:       <><rect x="2" y="2" width="20" height="8" rx="2" ry="2" stroke={color} strokeWidth="1.5" fill="none"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2" stroke={color} strokeWidth="1.5" fill="none"/><line x1="6" y1="6" x2="6.01" y2="6" stroke={color} strokeWidth="2"/><line x1="6" y1="18" x2="6.01" y2="18" stroke={color} strokeWidth="2"/></>,
    bell:         <><path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 01-3.46 0" stroke={color} strokeWidth="1.5" fill="none"/></>,
    search:       <><circle cx="11" cy="11" r="8" stroke={color} strokeWidth="1.5" fill="none"/><line x1="21" y1="21" x2="16.65" y2="16.65" stroke={color} strokeWidth="1.5"/></>,
    users:        <><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2" stroke={color} strokeWidth="1.5" fill="none"/><circle cx="9" cy="7" r="4" stroke={color} strokeWidth="1.5" fill="none"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75" stroke={color} strokeWidth="1.5" fill="none"/></>,
    clipboard:    <><path d="M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2" stroke={color} strokeWidth="1.5" fill="none"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1" stroke={color} strokeWidth="1.5" fill="none"/></>,
    trash:        <><polyline points="3,6 5,6 21,6" stroke={color} strokeWidth="1.5" fill="none"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2" stroke={color} strokeWidth="1.5" fill="none"/></>,
    alert:        <><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" stroke={color} strokeWidth="1.5" fill="none"/><line x1="12" y1="9" x2="12" y2="13" stroke={color} strokeWidth="1.5"/><line x1="12" y1="17" x2="12.01" y2="17" stroke={color} strokeWidth="2"/></>,
    home:         <><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" stroke={color} strokeWidth="1.5" fill="none"/><polyline points="9,22 9,12 15,12 15,22" stroke={color} strokeWidth="1.5" fill="none"/></>,
    check_circle: <><path d="M22 11.08V12a10 10 0 11-5.93-9.14" stroke={color} strokeWidth="1.5" fill="none"/><polyline points="22,4 12,14.01 9,11.01" stroke={color} strokeWidth="1.5" fill="none"/></>,
    x_circle:     <><circle cx="12" cy="12" r="10" stroke={color} strokeWidth="1.5" fill="none"/><line x1="15" y1="9" x2="9" y2="15" stroke={color} strokeWidth="1.5"/><line x1="9" y1="9" x2="15" y2="15" stroke={color} strokeWidth="1.5"/></>,
    info:         <><circle cx="12" cy="12" r="10" stroke={color} strokeWidth="1.5" fill="none"/><line x1="12" y1="16" x2="12" y2="12" stroke={color} strokeWidth="1.5"/><line x1="12" y1="8" x2="12.01" y2="8" stroke={color} strokeWidth="2"/></>,
    x:            <><line x1="18" y1="6" x2="6" y2="18" stroke={color} strokeWidth="1.5"/><line x1="6" y1="6" x2="18" y2="18" stroke={color} strokeWidth="1.5"/></>,
    filter:       <><polygon points="22,3 2,3 10,12.46 10,19 14,21 14,12.46" stroke={color} strokeWidth="1.5" fill="none"/></>,
    vendor:       <><path d="M20 7H4a2 2 0 00-2 2v10a2 2 0 002 2h16a2 2 0 002-2V9a2 2 0 00-2-2z" stroke={color} strokeWidth="1.5" fill="none"/><path d="M16 21V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v16" stroke={color} strokeWidth="1.5" fill="none"/></>,
    grid:         <><rect x="3" y="3" width="8" height="8" rx="1.5" stroke={color} strokeWidth="1.5" fill="none"/><rect x="13" y="3" width="8" height="8" rx="1.5" stroke={color} strokeWidth="1.5" fill="none"/><rect x="3" y="13" width="8" height="8" rx="1.5" stroke={color} strokeWidth="1.5" fill="none"/><rect x="13" y="13" width="8" height="8" rx="1.5" stroke={color} strokeWidth="1.5" fill="none"/></>,
    settings:     <><circle cx="12" cy="12" r="3" stroke={color} strokeWidth="1.5" fill="none"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z" stroke={color} strokeWidth="1.5" fill="none"/></>,
    plus:         <><line x1="12" y1="5" x2="12" y2="19" stroke={color} strokeWidth="1.8"/><line x1="5" y1="12" x2="19" y2="12" stroke={color} strokeWidth="1.8"/></>,
    cloud:        <><path d="M18 10h-1.26A8 8 0 109 20h9a5 5 0 000-10z" stroke={color} strokeWidth="1.5" fill="none"/></>,
    chevron_right:<><polyline points="9,18 15,12 9,6" stroke={color} strokeWidth="1.5" fill="none"/></>,
    chevron_left: <><polyline points="15,18 9,12 15,6" stroke={color} strokeWidth="1.5" fill="none"/></>,
    book:         <><path d="M4 19.5A2.5 2.5 0 016.5 17H20" stroke={color} strokeWidth="1.5" fill="none"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z" stroke={color} strokeWidth="1.5" fill="none"/></>,
    activity:     <><polyline points="22,12 18,12 15,21 9,3 6,12 2,12" stroke={color} strokeWidth="1.5" fill="none"/></>,
    check_square: <><polyline points="9,11 12,14 22,4" stroke={color} strokeWidth="1.5" fill="none"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11" stroke={color} strokeWidth="1.5" fill="none"/></>,
    calendar:     <><rect x="3" y="4" width="18" height="18" rx="2" ry="2" stroke={color} strokeWidth="1.5" fill="none"/><line x1="16" y1="2" x2="16" y2="6" stroke={color} strokeWidth="1.5"/><line x1="8" y1="2" x2="8" y2="6" stroke={color} strokeWidth="1.5"/><line x1="3" y1="10" x2="21" y2="10" stroke={color} strokeWidth="1.5"/></>,
    bar_chart:    <><line x1="18" y1="20" x2="18" y2="10" stroke={color} strokeWidth="1.5"/><line x1="12" y1="20" x2="12" y2="4" stroke={color} strokeWidth="1.5"/><line x1="6" y1="20" x2="6" y2="14" stroke={color} strokeWidth="1.5"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display:'block' }}>
      {icons[name] || icons['folder']}
    </svg>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// EmptyState
// ─────────────────────────────────────────────────────────────────────────────
const EmptyState = ({
  icon = 'folder',
  title,
  description,
  primaryAction,   // { label, onClick }
  secondaryAction, // { label, onClick }
  compact = false,
}) => {
  const s = {
    wrap: {
      display: 'flex', flexDirection: 'column', alignItems: 'center',
      justifyContent: 'center', padding: compact ? '32px 24px' : '64px 24px',
      textAlign: 'center', fontFamily: DS.font, direction: 'rtl',
      gap: compact ? 8 : 16,
    },
    iconWrap: {
      width: compact ? 56 : 80, height: compact ? 56 : 80,
      borderRadius: '50%',
      background: 'var(--ybp-row-hover, #f3f4f6)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    },
    title: {
      margin: 0,
      fontSize: compact ? 15 : 18,
      fontWeight: 700,
      color: 'var(--ybp-ink, #111827)',
    },
    desc: {
      margin: 0,
      fontSize: compact ? 13 : 14,
      color: 'var(--ybp-ink-faint, #6b7280)',
      maxWidth: 280,
    },
    actions: { display: 'flex', gap: 10, flexWrap: 'wrap', justifyContent: 'center', marginTop: 4 },
    primary: {
      padding: '10px 20px', borderRadius: 8,
      background: DS.navy, color: '#fff',
      border: 'none', fontSize: 14, fontWeight: 600,
      cursor: 'pointer', fontFamily: DS.font,
    },
    secondary: {
      padding: '10px 20px', borderRadius: 8,
      background: 'transparent', color: DS.navy,
      border: `1.5px solid ${DS.navy}`, fontSize: 14, fontWeight: 600,
      cursor: 'pointer', fontFamily: DS.font,
    },
  };

  return (
    <div style={s.wrap}>
      <div style={s.iconWrap}>
        <DSIcon name={icon} size={compact ? 28 : 40} color={DS.gray} />
      </div>
      {title && <h3 style={s.title}>{title}</h3>}
      {description && <p style={s.desc}>{description}</p>}
      {(primaryAction || secondaryAction) && (
        <div style={s.actions}>
          {primaryAction && (
            <button style={s.primary} onClick={primaryAction.onClick}>
              {primaryAction.label}
            </button>
          )}
          {secondaryAction && (
            <button style={s.secondary} onClick={secondaryAction.onClick}>
              {secondaryAction.label}
            </button>
          )}
        </div>
      )}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// ErrorState
// ─────────────────────────────────────────────────────────────────────────────
const ERROR_CONFIGS = {
  network: {
    icon: 'wifi_off', color: DS.yellow,
    title: 'אין חיבור לרשת',
    description: 'בדוק את החיבור לאינטרנט ונסה שוב.',
    actionLabel: 'נסה שוב',
  },
  permission: {
    icon: 'lock', color: DS.red,
    title: 'אין הרשאה',
    description: 'אין לך הרשאה לצפות בתוכן זה. פנה למנהל המערכת.',
    actionLabel: 'פנה למנהל',
  },
  404: {
    icon: 'compass', color: DS.gray,
    title: 'הדף לא נמצא',
    description: 'הדף שחיפשת אינו קיים או הוסר.',
    actionLabel: 'חזור לבית',
  },
  500: {
    icon: 'server', color: DS.red,
    title: 'שגיאת שרת',
    description: 'אירעה שגיאה בשרת. אנחנו עובדים על פתרון.',
    actionLabel: 'צור קשר עם תמיכה',
  },
  validation: {
    icon: 'alert', color: DS.yellow,
    title: 'שגיאה בטופס',
    description: 'יש שדות שצריכים תשומת לב.',
    actionLabel: null,
  },
};

const ErrorState = ({ type = 'network', title, description, onRetry, onContact, onBack }) => {
  const cfg = ERROR_CONFIGS[type] || ERROR_CONFIGS['500'];
  const s = {
    wrap: {
      display: 'flex', flexDirection: 'column', alignItems: 'center',
      padding: '64px 24px', textAlign: 'center',
      fontFamily: DS.font, direction: 'rtl', gap: 16,
    },
    iconWrap: {
      width: 80, height: 80, borderRadius: '50%',
      background: cfg.color + '18',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    },
    title: { margin: 0, fontSize: 18, fontWeight: 700, color: 'var(--ybp-ink,#111827)' },
    desc:  { margin: 0, fontSize: 14, color: 'var(--ybp-ink-faint,#6b7280)', maxWidth: 300 },
    btn: {
      padding: '10px 24px', borderRadius: 8,
      background: cfg.color === DS.red ? DS.red : DS.navy,
      color: '#fff', border: 'none', fontSize: 14, fontWeight: 600,
      cursor: 'pointer', fontFamily: DS.font, marginTop: 4,
    },
  };
  const handleAction = () => {
    if (onRetry) onRetry();
    else if (onContact) onContact();
    else if (onBack) onBack();
  };
  return (
    <div style={s.wrap}>
      <div style={s.iconWrap}>
        <DSIcon name={cfg.icon} size={40} color={cfg.color} />
      </div>
      <h3 style={s.title}>{title || cfg.title}</h3>
      <p style={s.desc}>{description || cfg.description}</p>
      {cfg.actionLabel && (
        <button style={s.btn} onClick={handleAction}>{cfg.actionLabel}</button>
      )}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// LoadingSkeleton
// ─────────────────────────────────────────────────────────────────────────────
const shimmerStyle = `
@keyframes ybp-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.ybp-shimmer {
  background: linear-gradient(90deg,
    var(--ybp-border,#e5e7eb) 25%,
    var(--ybp-row-hover,#f3f4f6) 50%,
    var(--ybp-border,#e5e7eb) 75%
  );
  background-size: 200% 100%;
  animation: ybp-shimmer 1.5s infinite;
  border-radius: 6px;
}
`;

const SkeletonBox = ({ w = '100%', h = 16, rounded = 6, mb = 0, style: extraStyle = {} }) => (
  <div className="ybp-shimmer" style={{ width: w, height: h, borderRadius: rounded, marginBottom: mb, ...extraStyle }} />
);

const LoadingSkeleton = ({ type = 'cards', count = 3 }) => {
  // inject shimmer CSS once
  if (!document.getElementById('ybp-shimmer-style')) {
    const st = document.createElement('style');
    st.id = 'ybp-shimmer-style';
    st.textContent = shimmerStyle;
    document.head.appendChild(st);
  }

  const s = {
    card: {
      background: 'var(--ybp-panel,#fff)',
      border: '1px solid var(--ybp-border,#e5e7eb)',
      borderRadius: 10, padding: 16, marginBottom: 12,
      display: 'flex', flexDirection: 'column', gap: 10,
    },
    row: { display: 'flex', gap: 12, alignItems: 'center', marginBottom: 8 },
  };

  if (type === 'cards') {
    return (
      <div style={{ padding: '16px', direction: 'rtl' }}>
        {Array.from({ length: count }).map((_, i) => (
          <div key={i} style={s.card}>
            <div style={s.row}>
              <SkeletonBox w={40} h={40} rounded={8} />
              <div style={{ flex: 1 }}>
                <SkeletonBox h={14} w="60%" mb={6} />
                <SkeletonBox h={11} w="40%" />
              </div>
            </div>
            <SkeletonBox h={11} w="90%" />
            <SkeletonBox h={11} w="75%" />
          </div>
        ))}
      </div>
    );
  }

  if (type === 'rows') {
    return (
      <div style={{ padding: '0 16px', direction: 'rtl' }}>
        {Array.from({ length: count }).map((_, i) => (
          <div key={i} style={{ ...s.row, padding: '12px 0', borderBottom: '1px solid var(--ybp-border,#e5e7eb)' }}>
            <SkeletonBox w={32} h={32} rounded={16} />
            <div style={{ flex: 1 }}>
              <SkeletonBox h={13} w={`${50 + (i * 13) % 30}%`} mb={5} />
              <SkeletonBox h={10} w={`${30 + (i * 7) % 20}%`} />
            </div>
            <SkeletonBox w={60} h={22} rounded={4} />
          </div>
        ))}
      </div>
    );
  }

  if (type === 'gantt') {
    return (
      <div style={{ padding: 16, direction: 'rtl' }}>
        {Array.from({ length: count }).map((_, i) => (
          <div key={i} style={s.row}>
            <SkeletonBox w={120} h={14} rounded={4} />
            <SkeletonBox w={`${30 + (i * 17) % 40}%`} h={24} rounded={4} style={{ marginRight: `${(i * 11) % 20}%` }} />
          </div>
        ))}
      </div>
    );
  }

  if (type === 'detail') {
    return (
      <div style={{ padding: 16, direction: 'rtl' }}>
        <div style={{ ...s.card, marginBottom: 16 }}>
          <SkeletonBox h={20} w="50%" />
          <SkeletonBox h={12} w="30%" />
          <div style={{ display: 'flex', gap: 8 }}>
            {[1,2,3].map(i => <SkeletonBox key={i} w={80} h={32} rounded={8} />)}
          </div>
        </div>
        {[80, 65, 75].map((w, i) => (
          <div key={i} style={s.card}>
            <SkeletonBox h={13} w={`${w}%`} />
            <SkeletonBox h={11} w="90%" />
          </div>
        ))}
      </div>
    );
  }

  // default: single block
  return (
    <div style={{ padding: 16 }}>
      <SkeletonBox h={200} rounded={10} />
    </div>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// Toast System
// ─────────────────────────────────────────────────────────────────────────────
let _toastContainer = null;
let _toastSetState = null;
let _toastIdCounter = 0;

const TOAST_ICONS = {
  success: { icon: 'check_circle', color: DS.green,  bg: '#f0fdf4', border: '#bbf7d0' },
  error:   { icon: 'x_circle',     color: DS.red,    bg: '#fef2f2', border: '#fecaca' },
  warning: { icon: 'alert',        color: DS.yellow, bg: '#fffbeb', border: '#fde68a' },
  info:    { icon: 'info',         color: DS.blue,   bg: '#eff6ff', border: '#bfdbfe' },
  loading: { icon: null,           color: DS.gray,   bg: '#f9fafb', border: '#e5e7eb' },
};

function _showToast(type, message, duration) {
  if (!_toastSetState) {
    _ensureToastMount();
    setTimeout(() => _showToast(type, message, duration), 100);
    return;
  }
  const id = ++_toastIdCounter;
  const ms = duration !== undefined ? duration : (type === 'error' ? 5000 : type === 'loading' ? 0 : 3000);
  _toastSetState(prev => [...prev, { id, type, message, ms }]);
  if (ms > 0) setTimeout(() => _dismissToast(id), ms);
  return id;
}

function _dismissToast(id) {
  if (_toastSetState) _toastSetState(prev => prev.filter(t => t.id !== id));
}

function _ensureToastMount() {
  if (_toastContainer) return;
  _toastContainer = document.createElement('div');
  _toastContainer.id = 'ybp-toast-root';
  document.body.appendChild(_toastContainer);
  const { createRoot } = ReactDOM;
  const root = createRoot(_toastContainer);
  root.render(React.createElement(ToastContainer));
}

const ToastContainer = () => {
  const [toasts, setToasts] = React.useState([]);
  _toastSetState = setToasts;

  const isMobile = window.innerWidth < 600;

  const s = {
    wrap: {
      position: 'fixed',
      ...(isMobile
        ? { bottom: 80, left: '50%', transform: 'translateX(-50%)', width: 'calc(100vw - 32px)' }
        : { top: 20, left: 20 }),  // RTL: left = visual right in rtl context
      zIndex: 99999,
      display: 'flex', flexDirection: 'column', gap: 8,
      fontFamily: DS.font, direction: 'rtl',
      pointerEvents: 'none',
    },
  };

  return (
    <div style={s.wrap}>
      {toasts.slice(-3).map(t => {
        const cfg = TOAST_ICONS[t.type] || TOAST_ICONS.info;
        return (
          <div key={t.id} style={{
            background: cfg.bg,
            border: `1px solid ${cfg.border}`,
            borderRadius: 10,
            padding: '12px 16px',
            display: 'flex', alignItems: 'center', gap: 10,
            boxShadow: '0 4px 16px rgba(0,0,0,0.10)',
            pointerEvents: 'all',
            minWidth: isMobile ? undefined : 280,
            maxWidth: isMobile ? undefined : 360,
            animation: 'ybp-toast-in 0.2s ease',
          }}>
            {t.type === 'loading'
              ? <div style={{ width:18, height:18, border:`2px solid ${DS.gray}`, borderTopColor:'transparent', borderRadius:'50%', animation:'ybp-spin 0.8s linear infinite' }} />
              : <DSIcon name={cfg.icon} size={18} color={cfg.color} />
            }
            <span style={{ flex:1, fontSize:14, fontWeight:500, color:'#111827', lineHeight:1.4 }}>{t.message}</span>
            <button onClick={() => _dismissToast(t.id)} style={{
              background:'none', border:'none', cursor:'pointer', padding:2, display:'flex', alignItems:'center',
            }}>
              <DSIcon name="x" size={14} color={DS.gray} />
            </button>
          </div>
        );
      })}
    </div>
  );
};

// inject toast animation CSS
(function() {
  if (document.getElementById('ybp-toast-style')) return;
  const st = document.createElement('style');
  st.id = 'ybp-toast-style';
  st.textContent = `
    @keyframes ybp-toast-in { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } }
    @keyframes ybp-spin { to { transform: rotate(360deg); } }
  `;
  document.head.appendChild(st);
})();

// Public API
const toastSuccess = (msg, ms) => _showToast('success', msg, ms);
const toastError   = (msg, ms) => _showToast('error', msg, ms);
const toastWarning = (msg, ms) => _showToast('warning', msg, ms);
const toastInfo    = (msg, ms) => _showToast('info', msg, ms);
const toastLoading = (msg)     => _showToast('loading', msg, 0);
const toastDismiss = (id)      => _dismissToast(id);

// ─────────────────────────────────────────────────────────────────────────────
// ConfirmDialog
// ─────────────────────────────────────────────────────────────────────────────
const ConfirmDialog = ({
  isOpen,
  title,
  description,
  confirmLabel = 'אשר',
  cancelLabel  = 'ביטול',
  confirmVariant = 'primary', // 'primary' | 'danger'
  onConfirm,
  onCancel,
  requireInput, // string — user must type this to confirm
  children,
}) => {
  const [inputVal, setInputVal] = React.useState('');
  React.useEffect(() => { if (!isOpen) setInputVal(''); }, [isOpen]);
  if (!isOpen) return null;

  const canConfirm = !requireInput || inputVal.trim() === requireInput;

  const s = {
    overlay: {
      position: 'fixed', inset: 0,
      background: 'rgba(0,0,0,0.45)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 99990, padding: 16,
      fontFamily: DS.font, direction: 'rtl',
    },
    dialog: {
      background: 'var(--ybp-panel,#fff)',
      borderRadius: 12,
      padding: '24px',
      width: '100%', maxWidth: 380,
      boxShadow: '0 20px 60px rgba(0,0,0,0.2)',
    },
    title: { margin: '0 0 8px', fontSize: 17, fontWeight: 700, color: 'var(--ybp-ink,#111827)' },
    desc:  { margin: '0 0 16px', fontSize: 14, color: 'var(--ybp-ink-faint,#6b7280)', lineHeight: 1.5 },
    input: {
      width: '100%', padding: '10px 12px', borderRadius: 8,
      border: `1.5px solid var(--ybp-border,#e5e7eb)`,
      fontSize: 14, fontFamily: DS.font,
      marginBottom: 16, boxSizing: 'border-box',
      background: 'var(--ybp-input-bg,#fff)',
      color: 'var(--ybp-ink,#111827)',
      direction: 'rtl', outline: 'none',
    },
    row: { display: 'flex', gap: 10, justifyContent: 'flex-end' },
    cancelBtn: {
      padding: '10px 18px', borderRadius: 8,
      background: 'var(--ybp-row-hover,#f3f4f6)',
      border: '1px solid var(--ybp-border,#e5e7eb)',
      color: 'var(--ybp-ink,#111827)',
      fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: DS.font,
    },
    confirmBtn: {
      padding: '10px 18px', borderRadius: 8,
      background: confirmVariant === 'danger' ? DS.red : DS.navy,
      color: '#fff',
      border: 'none',
      fontSize: 14, fontWeight: 600,
      cursor: canConfirm ? 'pointer' : 'not-allowed',
      fontFamily: DS.font,
      opacity: canConfirm ? 1 : 0.5,
    },
  };

  return (
    <div style={s.overlay} onClick={e => { if (e.target === e.currentTarget) onCancel && onCancel(); }}>
      <div style={s.dialog}>
        {title && <h3 style={s.title}>{title}</h3>}
        {description && <p style={s.desc}>{description}</p>}
        {children}
        {requireInput && (
          <div>
            <div style={{ fontSize:12, color: DS.gray, marginBottom:6 }}>
              הקלד <strong>"{requireInput}"</strong> כדי לאשר:
            </div>
            <input
              style={s.input}
              value={inputVal}
              onChange={e => setInputVal(e.target.value)}
              placeholder={requireInput}
              autoFocus
            />
          </div>
        )}
        <div style={s.row}>
          {/* RTL: cancel on left (visual right), confirm on right (visual left) */}
          <button style={s.cancelBtn} onClick={onCancel}>{cancelLabel}</button>
          <button style={s.confirmBtn} disabled={!canConfirm} onClick={() => canConfirm && onConfirm && onConfirm()}>
            {confirmLabel}
          </button>
        </div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// FormField — wrapper אחיד לשדות טופס עם validation
// ─────────────────────────────────────────────────────────────────────────────
const FormField = ({ label, required, error, helper, children }) => (
  <div style={{ display:'flex', flexDirection:'column', gap:4, direction:'rtl', fontFamily:DS.font }}>
    {label && (
      <label style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft,#374151)', letterSpacing:0.3 }}>
        {label}{required && <span style={{ color:DS.red, marginRight:2 }}>*</span>}
      </label>
    )}
    {children}
    {error && (
      <span style={{ fontSize:11, color:DS.red, display:'flex', alignItems:'center', gap:4 }}>
        <DSIcon name="alert" size={12} color={DS.red} /> {error}
      </span>
    )}
    {helper && !error && (
      <span style={{ fontSize:11, color:DS.gray }}>{helper}</span>
    )}
  </div>
);

// ─────────────────────────────────────────────────────────────────────────────
// ReminderStatusBadge — badge צבעוני לפי תאריך יעד
// ─────────────────────────────────────────────────────────────────────────────
const ReminderStatusBadge = ({ dueDate, status }) => {
  if (status === 'done') return null;
  const now = Date.now();
  const due = new Date(dueDate).getTime();
  const daysLeft = Math.ceil((due - now) / 86400000);

  let color, bg, label;
  if (daysLeft < 0) {
    color = DS.red; bg = '#fef2f2'; label = `איחור ${Math.abs(daysLeft)} ימים`;
  } else if (daysLeft < 3) {
    color = DS.red; bg = '#fef2f2'; label = daysLeft === 0 ? 'היום' : `${daysLeft} ימים`;
  } else if (daysLeft < 7) {
    color = DS.yellow; bg = '#fffbeb'; label = `${daysLeft} ימים`;
  } else {
    color = DS.green; bg = '#f0fdf4'; label = `${daysLeft} ימים`;
  }

  return (
    <span style={{
      display:'inline-flex', alignItems:'center', gap:3,
      padding:'2px 7px', borderRadius:99,
      background:bg, color, fontSize:11, fontWeight:600,
      fontFamily:DS.font,
    }}>
      <span style={{ width:6, height:6, borderRadius:'50%', background:color, display:'inline-block' }} />
      {label}
    </span>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// StatusBadge — badge סטטוס אחיד
// ─────────────────────────────────────────────────────────────────────────────
const StatusBadge = ({ status, label, size = 'sm' }) => {
  const configs = {
    done:     { color: DS.green,  bg: '#f0fdf4', text: 'בוצע' },
    open:     { color: DS.red,    bg: '#fef2f2', text: 'פתוח' },
    pending:  { color: DS.yellow, bg: '#fffbeb', text: 'בהמתנה' },
    progress: { color: DS.blue,   bg: '#eff6ff', text: 'בתהליך' },
    draft:    { color: DS.gray,   bg: '#f9fafb', text: 'טיוטה' },
    winner:   { color: DS.green,  bg: '#f0fdf4', text: 'זוכה' },
    lost:     { color: DS.gray,   bg: '#f9fafb', text: 'לא נבחר' },
  };
  const cfg = configs[status] || { color: DS.gray, bg: '#f9fafb', text: status };
  const sz = size === 'sm' ? { fontSize:11, padding:'2px 8px' } : { fontSize:13, padding:'4px 12px' };
  return (
    <span style={{
      display:'inline-block', borderRadius:99,
      background:cfg.bg, color:cfg.color,
      fontWeight:600, fontFamily:DS.font,
      ...sz,
    }}>
      {label || cfg.text}
    </span>
  );
};

// ─────────────────────────────────────────────────────────────────────────────
// Export to window
// ─────────────────────────────────────────────────────────────────────────────
Object.assign(window, {
  // Components
  EmptyState,
  ErrorState,
  LoadingSkeleton,
  ToastContainer,
  ConfirmDialog,
  FormField,
  ReminderStatusBadge,
  StatusBadge,
  DSIcon,

  // Toast functions
  toastSuccess,
  toastError,
  toastWarning,
  toastInfo,
  toastLoading,
  toastDismiss,

  // Design tokens
  DS,
});

// mount ToastContainer immediately
_ensureToastMount();
