
// Shared design system — Promoup 360°

const DS = {
  colors: {
    primary: '#EA6B00',
    primaryDark: '#C45508',
    primaryLight: '#FFF4E6',
    success: '#10B981',
    successLight: '#ECFDF5',
    warning: '#F59E0B',
    warningLight: '#FFFBEB',
    danger: '#EF4444',
    dangerLight: '#FEF2F2',
    sidebar: '#12085C',
    sidebarHover: '#1C1280',
    sidebarActive: '#EA6B00',
    bg: '#F8F5FF',
    card: '#FFFFFF',
    border: '#E2E8F0',
    text: '#0F172A',
    textSec: '#64748B',
    textMuted: '#94A3B8',
    purple: '#7B35C8',
  },
  radius: { sm: '8px', md: '12px', lg: '16px', xl: '20px', full: '9999px' },
  shadow: {
    sm: '0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04)',
    md: '0 4px 12px rgba(0,0,0,0.06), 0 2px 6px rgba(0,0,0,0.04)',
    lg: '0 10px 30px rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.04)',
  }
};

// Icon library — simple SVG paths
const iconPaths = {
  dashboard: 'M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M9 22V12h6v10',
  calendar: 'M8 2v4 M16 2v4 M3 10h18 M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z',
  budget: 'M12 2v20 M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6',
  users: 'M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75',
  crm: 'M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2 M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',
  tasks: 'M9 11l3 3L22 4 M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11',
  portal: 'M3 9a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z M3 9l9 6 9-6',
  reports: 'M18 20V10 M12 20V4 M6 20v-6',
  wallet: 'M21 12V7H5a2 2 0 0 1 0-4h14v4 M3 5v14a2 2 0 0 0 2 2h16v-5 M18 12a2 2 0 0 0 0 4h4v-4z',
  bell: 'M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9 M13.73 21a2 2 0 0 1-3.46 0',
  search: 'M21 21l-4.35-4.35 M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z',
  plus: 'M12 5v14 M5 12h14',
  x: 'M18 6L6 18 M6 6l12 12',
  check: 'M20 6L9 17l-5-5',
  arrow: 'M5 12h14 M12 5l7 7-7 7',
  arrowDown: 'M12 5v14 M19 12l-7 7-7-7',
  edit: 'M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z',
  trash: 'M3 6h18 M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6 M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2',
  mail: 'M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z M22 6l-10 7L2 6',
  phone: 'M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.15 12.91a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.06 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21 16.92z',
  star: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z',
  link: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71 M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',
  download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3',
  eye: 'M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z M12 12a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  filter: 'M22 3H2l8 9.46V19l4 2v-8.54L22 3z',
  grid: 'M3 3h7v7H3z M14 3h7v7h-7z M14 14h7v7h-7z M3 14h7v7H3z',
  list: 'M8 6h13 M8 12h13 M8 18h13 M3 6h.01 M3 12h.01 M3 18h.01',
  settings: 'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z',
  logout: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4 M16 17l5-5-5-5 M21 12H9',
  message: 'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z',
  trending: 'M23 6l-9.5 9.5-5-5L1 18 M17 6h6v6',
  clock: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 6v6l4 2',
  alert: 'M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z M12 9v4 M12 17h.01',
  chevronRight: 'M9 18l6-6-6-6',
  chevronLeft: 'M15 18l-6-6 6-6',
  chevronDown: 'M6 9l6 6 6-6',
  zap: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z',
  award: 'M12 15a7 7 0 1 0 0-14 7 7 0 0 0 0 14z M8.21 13.89L7 23l5-3 5 3-1.21-9.12',
  briefcase: 'M20 7H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z M16 7V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2',
  tag: 'M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z M7 7h.01',
  photo: 'M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z M12 17a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',
  map: 'M1 6v16l7-4 8 4 7-4V2l-7 4-8-4-7 4z M8 2v16 M16 6v16',
  cpu: 'M9 2H5a2 2 0 0 0-2 2v4 M15 2h4a2 2 0 0 0 2 2v4 M9 22H5a2 2 0 0 0-2-2v-4 M15 22h4a2 2 0 0 0 2-2v-4 M9 9h6v6H9z M2 9h2 M2 15h2 M20 9h2 M20 15h2 M9 2v2 M15 2v2 M9 20v2 M15 20v2',
};

function Icon({ name, size = 18, color = 'currentColor', strokeWidth = 1.8 }) {
  const d = iconPaths[name];
  if (!d) return null;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
      {d.split(' M').map((segment, i) => (
        <path key={i} d={(i === 0 ? '' : 'M') + segment} />
      ))}
    </svg>
  );
}

// Badge component
function Badge({ children, variant = 'default', size = 'sm' }) {
  const variants = {
    default: { bg: '#F1F5F9', color: '#475569' },
    primary: { bg: '#EFF6FF', color: '#2563EB' },
    success: { bg: '#ECFDF5', color: '#059669' },
    warning: { bg: '#FFFBEB', color: '#D97706' },
    danger: { bg: '#FEF2F2', color: '#DC2626' },
    purple: { bg: '#F5F3FF', color: '#7C3AED' },
  };
  const v = variants[variant] || variants.default;
  const padding = size === 'sm' ? '2px 8px' : '4px 12px';
  const fontSize = size === 'sm' ? '11px' : '12px';
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      background: v.bg, color: v.color,
      padding, fontSize, fontWeight: 600,
      borderRadius: DS.radius.full, letterSpacing: '0.02em',
      whiteSpace: 'nowrap',
    }}>{children}</span>
  );
}

// Card component
function Card({ children, style = {}, onClick, hover = false }) {
  const [hovered, setHovered] = React.useState(false);
  return (
    <div
      onClick={onClick}
      onMouseEnter={() => hover && setHovered(true)}
      onMouseLeave={() => hover && setHovered(false)}
      style={{
        background: DS.colors.card, borderRadius: DS.radius.md,
        boxShadow: hovered ? DS.shadow.md : DS.shadow.sm,
        border: `1px solid ${DS.colors.border}`,
        transition: 'all 0.18s ease',
        cursor: onClick ? 'pointer' : 'default',
        transform: hovered ? 'translateY(-1px)' : 'none',
        ...style,
      }}
    >{children}</div>
  );
}

// Button component
function Btn({ children, variant = 'primary', size = 'md', onClick, icon, style = {}, disabled = false }) {
  const [hovered, setHovered] = React.useState(false);
  const variants = {
    primary: { bg: DS.colors.primary, hover: DS.colors.primaryDark, color: '#fff', border: 'none' },
    secondary: { bg: '#fff', hover: '#F8FAFC', color: DS.colors.text, border: `1px solid ${DS.colors.border}` },
    ghost: { bg: 'transparent', hover: '#F1F5F9', color: DS.colors.textSec, border: 'none' },
    danger: { bg: '#FEF2F2', hover: '#FEE2E2', color: DS.colors.danger, border: 'none' },
    success: { bg: DS.colors.success, hover: '#059669', color: '#fff', border: 'none' },
  };
  const v = variants[variant] || variants.primary;
  const sizes = { sm: { padding: '6px 12px', fontSize: '12px' }, md: { padding: '8px 16px', fontSize: '13px' }, lg: { padding: '11px 22px', fontSize: '14px' } };
  const s = sizes[size] || sizes.md;
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        background: hovered ? v.hover : v.bg, color: v.color,
        border: v.border, borderRadius: DS.radius.sm,
        padding: s.padding, fontSize: s.fontSize, fontWeight: 600,
        cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
        transition: 'all 0.15s ease', whiteSpace: 'nowrap',
        ...style,
      }}
    >
      {icon && <Icon name={icon} size={14} color="currentColor" />}
      {children}
    </button>
  );
}

// Avatar
function Avatar({ name = '', size = 36, src, color }) {
  const colors = ['#3B82F6','#8B5CF6','#10B981','#F59E0B','#EF4444','#06B6D4','#EC4899'];
  const c = color || colors[name.charCodeAt(0) % colors.length];
  const initials = name.split(' ').map(w => w[0]).slice(0,2).join('').toUpperCase();
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: c, color: '#fff',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.36, fontWeight: 700, flexShrink: 0,
      overflow: 'hidden',
    }}>
      {src ? <img src={src} style={{width:'100%',height:'100%',objectFit:'cover'}} alt={name}/> : initials}
    </div>
  );
}

// Progress bar
function ProgressBar({ value, max = 100, color = DS.colors.primary, height = 6 }) {
  const pct = Math.min(100, (value / max) * 100);
  return (
    <div style={{ background: '#F1F5F9', borderRadius: DS.radius.full, height, overflow: 'hidden' }}>
      <div style={{ width: `${pct}%`, height: '100%', background: color, borderRadius: DS.radius.full, transition: 'width 0.4s ease' }} />
    </div>
  );
}

// Stat card
function StatCard({ label, value, delta, icon, color = DS.colors.primary, subtitle }) {
  const positive = delta >= 0;
  return (
    <Card style={{ padding: '20px 24px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div style={{ fontSize: 12, color: DS.colors.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 6 }}>{label}</div>
          <div style={{ fontSize: 28, fontWeight: 700, color: DS.colors.text, letterSpacing: '-0.02em' }}>{value}</div>
          {subtitle && <div style={{ fontSize: 12, color: DS.colors.textMuted, marginTop: 4 }}>{subtitle}</div>}
        </div>
        <div style={{ width: 44, height: 44, borderRadius: DS.radius.sm, background: color + '15', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon name={icon} size={20} color={color} />
        </div>
      </div>
      {delta !== undefined && (
        <div style={{ marginTop: 12, display: 'flex', alignItems: 'center', gap: 4, fontSize: 12, color: positive ? DS.colors.success : DS.colors.danger }}>
          <Icon name={positive ? 'trending' : 'arrowDown'} size={13} color={positive ? DS.colors.success : DS.colors.danger} />
          <span style={{ fontWeight: 600 }}>{positive ? '+' : ''}{delta}%</span>
          <span style={{ color: DS.colors.textMuted }}>vs last month</span>
        </div>
      )}
    </Card>
  );
}

// Empty state
function EmptyState({ icon = 'grid', title = 'Nothing here yet', desc = '', action }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '60px 24px', textAlign: 'center' }}>
      <div style={{ width: 64, height: 64, borderRadius: DS.radius.md, background: '#F1F5F9', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16 }}>
        <Icon name={icon} size={28} color={DS.colors.textMuted} />
      </div>
      <div style={{ fontSize: 16, fontWeight: 600, color: DS.colors.text, marginBottom: 8 }}>{title}</div>
      <div style={{ fontSize: 13, color: DS.colors.textSec, maxWidth: 280, lineHeight: 1.5 }}>{desc}</div>
      {action && <div style={{ marginTop: 20 }}>{action}</div>}
    </div>
  );
}

// Modal
function Modal({ open, onClose, title, children, width = 520, extra }) {
  if (!open) return null;
  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.5)', backdropFilter: 'blur(4px)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }} onClick={onClose}>
      <div style={{ background: '#fff', borderRadius: DS.radius.lg, width: '100%', maxWidth: width, maxHeight: '90vh', overflow: 'auto', boxShadow: '0 25px 60px rgba(0,0,0,0.2)' }} onClick={e => e.stopPropagation()}>
        <div style={{ padding: '16px 24px', borderBottom: `1px solid ${DS.colors.border}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
          <div style={{ fontSize: 16, fontWeight: 700, color: DS.colors.text }}>{title}</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginLeft: 'auto' }}>
            {extra}
            <Btn variant="ghost" size="sm" onClick={onClose} icon="x" style={{ padding: 6 }}></Btn>
          </div>
        </div>
        <div style={{ padding: 24 }}>{children}</div>
      </div>
    </div>
  );
}

// Input
function Input({ label, value, onChange, placeholder, type = 'text', style = {}, list, onBlur }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, ...style }}>
      {label && <label style={{ fontSize: 12, fontWeight: 600, color: DS.colors.textSec }}>{label}</label>}
      <input
        type={type} value={value} onChange={e => onChange(e.target.value)} placeholder={placeholder}
        list={list}
        style={{
          border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm,
          padding: '9px 12px', fontSize: 13, color: DS.colors.text,
          outline: 'none', transition: 'border 0.15s',
          fontFamily: 'inherit',
        }}
        onFocus={e => e.target.style.borderColor = DS.colors.primary}
        onBlur={e => { e.target.style.borderColor = DS.colors.border; if (onBlur) onBlur(e); }}
      />
    </div>
  );
}

// Select
function Select({ label, value, onChange, options, style = {} }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, ...style }}>
      {label && <label style={{ fontSize: 12, fontWeight: 600, color: DS.colors.textSec }}>{label}</label>}
      <select
        value={value} onChange={e => onChange(e.target.value)}
        style={{
          border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm,
          padding: '9px 12px', fontSize: 13, color: DS.colors.text,
          outline: 'none', background: '#fff', fontFamily: 'inherit',
        }}
      >
        {options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
    </div>
  );
}

// Divider
function Divider({ style = {} }) {
  return <div style={{ height: 1, background: DS.colors.border, margin: '16px 0', ...style }} />;
}

// Section header
function SectionHeader({ title, subtitle, action }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 20 }}>
      <div>
        <h2 style={{ fontSize: 20, fontWeight: 700, color: DS.colors.text, margin: 0 }}>{title}</h2>
        {subtitle && <p style={{ fontSize: 13, color: DS.colors.textSec, margin: '4px 0 0' }}>{subtitle}</p>}
      </div>
      {action}
    </div>
  );
}

// Mini chart (bar chart using divs)
function MiniBarChart({ data, color = DS.colors.primary, height = 80 }) {
  const max = Math.max(...data.map(d => d.value));
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6, height }}>
      {data.map((d, i) => (
        <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, height: '100%', justifyContent: 'flex-end' }}>
          <div style={{
            width: '100%', background: color + '22', borderRadius: '4px 4px 0 0',
            height: `${(d.value / max) * (height - 20)}px`,
            position: 'relative', overflow: 'visible',
            transition: 'height 0.4s ease',
          }}>
            <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, background: color, borderRadius: '4px 4px 0 0', height: '100%', opacity: 0.85 }} />
          </div>
          <div style={{ fontSize: 10, color: DS.colors.textMuted, whiteSpace: 'nowrap' }}>{d.label}</div>
        </div>
      ))}
    </div>
  );
}

// Donut chart (SVG)
function DonutChart({ segments, size = 120 }) {
  const total = segments.reduce((s, seg) => s + seg.value, 0);
  let angle = -90;
  const r = 40, cx = 60, cy = 60;
  const paths = segments.map(seg => {
    const pct = seg.value / total;
    const sweep = pct * 360;
    const startAngle = angle;
    angle += sweep;
    const x1 = cx + r * Math.cos((startAngle * Math.PI) / 180);
    const y1 = cy + r * Math.sin((startAngle * Math.PI) / 180);
    const x2 = cx + r * Math.cos(((startAngle + sweep) * Math.PI) / 180);
    const y2 = cy + r * Math.sin(((startAngle + sweep) * Math.PI) / 180);
    const large = sweep > 180 ? 1 : 0;
    return { d: `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} Z`, color: seg.color, label: seg.label, value: seg.value };
  });
  return (
    <svg width={size} height={size} viewBox="0 0 120 120">
      <circle cx={60} cy={60} r={r} fill="white" />
      {paths.map((p, i) => <path key={i} d={p.d} fill={p.color} opacity={0.85} />)}
      <circle cx={60} cy={60} r={26} fill="white" />
    </svg>
  );
}

// Toast notification
function Toast({ message, type = 'success', onClose }) {
  React.useEffect(() => {
    const t = setTimeout(onClose, 3000);
    return () => clearTimeout(t);
  }, []);
  const colors = { success: DS.colors.success, danger: DS.colors.danger, warning: DS.colors.warning };
  return (
    <div style={{
      position: 'fixed', bottom: 24, right: 24, zIndex: 2000,
      background: '#1E293B', color: '#fff', borderRadius: DS.radius.md,
      padding: '12px 16px', display: 'flex', alignItems: 'center', gap: 10,
      boxShadow: DS.shadow.lg, fontSize: 13, fontWeight: 500, minWidth: 240,
      animation: 'slideIn 0.2s ease',
    }}>
      <div style={{ width: 6, height: 6, borderRadius: '50%', background: colors[type] || colors.success, flexShrink: 0 }} />
      {message}
    </div>
  );
}

// Loading spinner
function Spinner({ size = 32 }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 60 }}>
      <div style={{
        width: size, height: size, borderRadius: '50%',
        border: `3px solid ${DS.colors.border}`,
        borderTopColor: DS.colors.primary,
        animation: 'spin 0.7s linear infinite',
      }} />
    </div>
  );
}

// ───────────────────────────────────────────────────────────
// Permissões por setor (department) + nível (role)
// ───────────────────────────────────────────────────────────

const DEPT_LABELS = {
  admin: 'Administração',
  comercial: 'Comercial',
  financeiro: 'Financeiro',
  producao: 'Produção',
  sdr: 'SDR',
  atendimento: 'Atendimento',
};

const DEPT_OPTIONS = [
  { value: '', label: '— Selecionar —' },
  { value: 'admin', label: 'Administração (vê tudo)' },
  { value: 'comercial', label: 'Comercial' },
  { value: 'financeiro', label: 'Financeiro' },
  { value: 'producao', label: 'Produção' },
  { value: 'sdr', label: 'SDR' },
  { value: 'atendimento', label: 'Atendimento' },
];

// Quais módulos do menu cada setor pode acessar.
// Regra do cliente: Admin e Financeiro veem TUDO. Os demais setores
// veem tudo EXCETO Financeiro (a página de transações). A restrição
// principal pros não-financeiros é não ver os VALORES R$ — isso é
// controlado por canSeeFinancials, não por canSeeModule.
// 'usuarios' fica separado — exige role='admin' independentemente do setor.
const ALL_MODULES_FULL = ['dashboard','budgets','events','freelancers','crm','fornecedores','servicos','financeiro','tasks','portal','reports','whatsapp'];
const ALL_MODULES_NO_FIN = ['dashboard','budgets','events','freelancers','crm','fornecedores','servicos','tasks','portal','reports','whatsapp'];
const DEPT_MODULES = {
  admin:       ALL_MODULES_FULL,
  financeiro:  ALL_MODULES_FULL,
  comercial:   ALL_MODULES_NO_FIN,
  producao:    ALL_MODULES_NO_FIN,
  sdr:         ALL_MODULES_NO_FIN,
  atendimento: ALL_MODULES_NO_FIN,
};

// Setores que podem ver valores em R$ (Dashboard, colunas de preço no orçamento, etc.)
const FINANCIAL_DEPTS = new Set(['admin', 'comercial', 'financeiro']);

function canSeeModule(user, moduleId) {
  if (!user) return false;
  if (moduleId === 'usuarios') return user.role === 'admin';
  const dept = user.department || 'atendimento';
  return (DEPT_MODULES[dept] || []).includes(moduleId);
}

function canSeeFinancials(user) {
  if (!user) return false;
  return FINANCIAL_DEPTS.has(user.department || '');
}

function canEditBudgets(user) {
  if (!user) return false;
  if (user.role === 'visualizador') return false;
  return FINANCIAL_DEPTS.has(user.department || '');
}

function isReadOnly(user) {
  return !user || user.role === 'visualizador';
}

function deptLabel(dept) {
  return DEPT_LABELS[dept] || '—';
}

// Tela de "sem permissão" reutilizável
function NoAccess({ moduleName }) {
  return (
    <div style={{ padding: '64px 24px', textAlign: 'center', color: DS.colors.textMuted }}>
      <Icon name="alert" size={42} color={DS.colors.border} />
      <div style={{ fontSize: 16, fontWeight: 700, color: DS.colors.textSec, marginTop: 16 }}>
        Acesso restrito
      </div>
      <div style={{ fontSize: 13, marginTop: 6, maxWidth: 360, margin: '6px auto 0' }}>
        Seu setor não tem permissão para acessar {moduleName ? `o módulo de ${moduleName}` : 'esta área'}.
        Fale com um administrador caso precise de acesso.
      </div>
    </div>
  );
}

// Export all to window
Object.assign(window, {
  DS, Icon, Badge, Card, Btn, Avatar, ProgressBar, StatCard,
  EmptyState, Modal, Input, Select, Divider, SectionHeader,
  MiniBarChart, DonutChart, Toast, Spinner,
  DEPT_LABELS, DEPT_OPTIONS, DEPT_MODULES,
  canSeeModule, canSeeFinancials, canEditBudgets, isReadOnly, deptLabel,
  NoAccess,
});
