// ===========================================================
// State primitives: EmptyState, Skeleton, ErrorState, LoadingSpinner
// Coder dùng các primitive này khắp app khi data đang load/rỗng/lỗi
// ===========================================================

function EmptyState({ icon = 'package', title, desc, action }) {
  return (
    <div className="empty">
      <div className="icon-wrap"><Icon name={icon} size={28}/></div>
      <div className="bold fg-1" style={{fontSize:16,marginBottom:6}}>{title}</div>
      <div className="text-sm fg-muted" style={{maxWidth:380,margin:'0 auto var(--space-4)'}}>{desc}</div>
      {action}
    </div>
  );
}

function ErrorState({ title = 'Có lỗi xảy ra', desc = 'Không thể tải dữ liệu — vui lòng thử lại.', onRetry }) {
  return (
    <div className="empty">
      <div className="icon-wrap" style={{background:'rgba(191,9,35,0.08)',color:'var(--status-sale)'}}>
        <Icon name="close" size={28}/>
      </div>
      <div className="bold fg-1" style={{fontSize:16,marginBottom:6}}>{title}</div>
      <div className="text-sm fg-muted" style={{maxWidth:380,margin:'0 auto var(--space-4)'}}>{desc}</div>
      {onRetry && (
        <button className="btn btn-secondary" onClick={onRetry}>
          <Icon name="refresh" size={14}/>Thử lại
        </button>
      )}
    </div>
  );
}

function Skeleton({ w = '100%', h = 16, radius = 4, style }) {
  return (
    <span style={{
      display:'inline-block',
      width: typeof w === 'number' ? w + 'px' : w,
      height: typeof h === 'number' ? h + 'px' : h,
      borderRadius: radius,
      background:'linear-gradient(90deg, var(--bg-soft) 0%, var(--bg-muted) 50%, var(--bg-soft) 100%)',
      backgroundSize:'200% 100%',
      animation:'skeleton-shimmer 1.4s ease-in-out infinite',
      ...style,
    }}/>
  );
}

function SkeletonRow({ cols = 5 }) {
  return (
    <tr>
      {Array.from({length: cols}).map((_, i) => (
        <td key={i}><Skeleton w={i === 0 ? '70%' : '50%'} h={14}/></td>
      ))}
    </tr>
  );
}

function LoadingSpinner({ size = 24, label }) {
  return (
    <div style={{display:'inline-flex',gap:8,alignItems:'center'}}>
      <svg width={size} height={size} viewBox="0 0 24 24" style={{animation:'spin 0.8s linear infinite'}}>
        <circle cx="12" cy="12" r="10" stroke="var(--bg-muted)" strokeWidth="3" fill="none"/>
        <path d="M22 12 A 10 10 0 0 1 12 22" stroke="var(--vs-light-blue)" strokeWidth="3" fill="none" strokeLinecap="round"/>
      </svg>
      {label && <span className="text-sm fg-muted">{label}</span>}
    </div>
  );
}

// Inject animation keyframes once
if (typeof document !== 'undefined' && !document.getElementById('__tvs-state-keyframes')) {
  const s = document.createElement('style');
  s.id = '__tvs-state-keyframes';
  s.textContent = `
    @keyframes skeleton-shimmer {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }
    @keyframes spin {
      to { transform: rotate(360deg); }
    }
  `;
  document.head.appendChild(s);
}

Object.assign(window, { EmptyState, ErrorState, Skeleton, SkeletonRow, LoadingSpinner });

// ===========================================================
// Global toast — vanilla (no React plumbing needed)
// Any onClick can call window.tvsToast('message') or
// window.tvsToast('message', 'demo') for the "coming soon" style.
// ===========================================================
window.tvsToast = function(msg, kind) {
  let host = document.getElementById('__tvs-toast-host');
  if (!host) {
    host = document.createElement('div');
    host.id = '__tvs-toast-host';
    host.style.cssText = 'position:fixed;bottom:24px;left:50%;transform:translateX(-50%);z-index:2000;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;';
    document.body.appendChild(host);
  }
  const isDemo = kind === 'demo';
  const el = document.createElement('div');
  el.style.cssText = `pointer-events:auto;background:${isDemo ? '#333' : '#012169'};color:#fff;padding:13px 20px;border-radius:8px;box-shadow:0 12px 36px rgba(1,33,105,0.28);display:flex;gap:11px;align-items:center;font:600 14px/1.4 Lato,system-ui,sans-serif;max-width:90vw;animation:tvsToastIn .26s cubic-bezier(.16,1,.3,1);`;
  el.innerHTML = `<span style="display:inline-flex;width:24px;height:24px;border-radius:50%;background:${isDemo ? 'rgba(255,255,255,0.16)' : '#41B6E6'};color:${isDemo ? '#fff' : '#012169'};align-items:center;justify-content:center;flex-shrink:0;">${isDemo ? '🔧' : '✓'}</span><span>${msg}</span>`;
  host.appendChild(el);
  setTimeout(() => { el.style.transition = 'opacity .3s, transform .3s'; el.style.opacity = '0'; el.style.transform = 'translateY(8px)'; setTimeout(() => el.remove(), 300); }, 2600);
};

// Convenience for placeholder/not-yet-built buttons
window.tvsDemo = function(feature) {
  window.tvsToast((feature || 'Tính năng này') + ' sẽ hoạt động ở bản chính thức', 'demo');
};

if (typeof document !== 'undefined' && !document.getElementById('__tvs-toast-keyframes')) {
  const s = document.createElement('style');
  s.id = '__tvs-toast-keyframes';
  s.textContent = `@keyframes tvsToastIn { from { opacity:0; transform:translateY(12px) } to { opacity:1; transform:none } }`;
  document.head.appendChild(s);
}
