// Shared UI primitives

const Pill = ({ children, bg, fg, border, style }) => (
  <span style={{
    display: 'inline-flex', alignItems: 'center', gap: 6,
    padding: '3px 9px', borderRadius: 999, fontSize: 11,
    fontWeight: 550, letterSpacing: 0.1,
    background: bg || 'transparent',
    color: fg || 'var(--ink-2)',
    border: border || '1px solid transparent',
    whiteSpace: 'nowrap',
    ...style,
  }}>{children}</span>
);

const Dot = ({ color, size = 8 }) => (
  <span style={{
    display: 'inline-block', width: size, height: size,
    borderRadius: '50%', background: color, flexShrink: 0,
  }} />
);

const Avatar = ({ m, size = 24, ring }) => {
  if (!m) return null;
  return (
    <div title={m.naam} style={{
      width: size, height: size, borderRadius: '50%',
      background: m.kleur, color: 'white',
      fontSize: size * 0.4, fontWeight: 600,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      boxShadow: ring ? `0 0 0 2px ${ring}` : 'none',
      flexShrink: 0, letterSpacing: 0,
    }}>{m.initials}</div>
  );
};

const AvatarStack = ({ ids, max = 4, size = 22 }) => {
  const list = ids.map(window.medewerkerById).filter(Boolean);
  const shown = list.slice(0, max);
  const extra = list.length - shown.length;
  return (
    <div style={{ display: 'flex', alignItems: 'center' }}>
      {shown.map((m, i) => (
        <div key={m.id} style={{ marginLeft: i === 0 ? 0 : -6 }}>
          <Avatar m={m} size={size} ring="var(--paper)" />
        </div>
      ))}
      {extra > 0 && (
        <div style={{
          marginLeft: -6, width: size, height: size, borderRadius: '50%',
          background: 'var(--surface-2)', color: 'var(--ink-2)',
          fontSize: size * 0.38, fontWeight: 600,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: '0 0 0 2px var(--paper)',
        }}>+{extra}</div>
      )}
    </div>
  );
};

const PrioPill = ({ prio }) => {
  const p = window.PRIORITY[prio];
  return <Pill bg={p.bg} fg={p.fg}>{p.label}</Pill>;
};

const TeamChip = ({ team, compact }) => {
  const c = window.TEAM_COLORS[team] || window.TEAM_COLORS['—'];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: compact ? '1px 6px' : '2px 8px',
      borderRadius: 4, fontSize: compact ? 10 : 11,
      fontWeight: 600, letterSpacing: 0.3,
      background: c.bg, color: c.fg,
    }}>
      <span style={{ width: 5, height: 5, borderRadius: '50%', background: c.dot }} />
      {team}
    </span>
  );
};

const DeadlineChip = ({ deadline, done }) => {
  if (done) return <Pill bg="oklch(0.96 0.03 150)" fg="oklch(0.42 0.10 150)">✓ {fmtDate(deadline)}</Pill>;
  const d = window.daysUntil(deadline);
  let bg = 'var(--surface-2)', fg = 'var(--ink-2)', prefix = '';
  if (d < 0) { bg = 'oklch(0.94 0.08 25)'; fg = 'oklch(0.38 0.18 25)'; prefix = '⚠ '; }
  else if (d === 0) { bg = 'oklch(0.94 0.07 55)'; fg = 'oklch(0.42 0.14 55)'; prefix = '● '; }
  else if (d <= 2) { bg = 'oklch(0.95 0.05 60)'; fg = 'oklch(0.45 0.12 55)'; }
  return <Pill bg={bg} fg={fg}>{prefix}{fmtRel(deadline)}</Pill>;
};

function fmtDate(iso) {
  const d = new Date(iso);
  return d.toLocaleDateString('nl-NL', { day: '2-digit', month: 'short' });
}

function fmtRel(iso) {
  const d = window.daysUntil(iso);
  if (d === 0) return 'vandaag';
  if (d === 1) return 'morgen';
  if (d === -1) return 'gisteren';
  if (d < 0) return `${-d} dgn te laat`;
  if (d < 7) return `over ${d} dgn`;
  return fmtDate(iso);
}

function fmtDateLong(iso) {
  const d = new Date(iso);
  return d.toLocaleDateString('nl-NL', { day: '2-digit', month: 'long' });
}

const Icon = ({ name, size = 16 }) => {
  const paths = {
    kanban: <><rect x="3" y="4" width="5" height="12" rx="1"/><rect x="10" y="4" width="5" height="8" rx="1"/><rect x="17" y="4" width="4" height="16" rx="1"/></>,
    today: <><rect x="3" y="5" width="18" height="16" rx="2"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="8" y1="3" x2="8" y2="7"/><line x1="16" y1="3" x2="16" y2="7"/></>,
    klant: <><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/></>,
    lijst: <><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/><circle cx="4" cy="6" r="0.5" fill="currentColor"/></>,
    team: <><circle cx="9" cy="8" r="3"/><circle cx="17" cy="10" r="2.5"/><path d="M3 21c0-3.3 2.7-6 6-6s6 2.7 6 6"/><path d="M14 21c0-2.5 1.7-4.5 4-5"/></>,
    search: <><circle cx="11" cy="11" r="7"/><line x1="20" y1="20" x2="16" y2="16"/></>,
    plus: <><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></>,
    filter: <path d="M4 5h16l-6 8v5l-4 2v-7z"/>,
    clock: <><circle cx="12" cy="12" r="9"/><polyline points="12,7 12,12 16,14"/></>,
    chat: <path d="M4 5h16v10H9l-5 4z"/>,
    attach: <path d="M16 8v8a4 4 0 01-8 0V6a2.5 2.5 0 015 0v9a1 1 0 01-2 0V7"/>,
    check: <polyline points="5,12 10,17 19,7"/>,
    alert: <><circle cx="12" cy="12" r="9"/><line x1="12" y1="8" x2="12" y2="13"/><circle cx="12" cy="16" r="0.5" fill="currentColor"/></>,
    chevron: <polyline points="9,6 15,12 9,18"/>,
    down: <polyline points="6,9 12,15 18,9"/>,
    edit: <><path d="M4 20h4l10-10-4-4L4 16z"/><path d="M13 7l4 4"/><path d="M4 20l3-1"/></>,
    x: <><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></>,
    drop: <path d="M12 3c-3 4-6 7-6 11a6 6 0 0012 0c0-4-3-7-6-11z"/>,
    sparkle: <path d="M12 3l2 6 6 2-6 2-2 6-2-6-6-2 6-2z"/>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19 12a7 7 0 00-.1-1.2l2-1.5-2-3.5-2.4 1a7 7 0 00-2-1.2l-.4-2.6h-4l-.4 2.6a7 7 0 00-2 1.2l-2.4-1-2 3.5 2 1.5A7 7 0 005 12c0 .4 0 .8.1 1.2l-2 1.5 2 3.5 2.4-1a7 7 0 002 1.2l.4 2.6h4l.4-2.6a7 7 0 002-1.2l2.4 1 2-3.5-2-1.5c.1-.4.1-.8.1-1.2z"/></>,
    bell: <><path d="M6 16h12l-1.5-2V10a4.5 4.5 0 00-9 0v4z"/><path d="M10 19a2 2 0 004 0"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      {paths[name] || null}
    </svg>
  );
};

// ─── Logo ───────────────────────────────────────────────
const Logo = () => (
  <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
    <div style={{
      width: 32, height: 32, borderRadius: 8,
      background: 'linear-gradient(135deg, oklch(0.60 0.18 30), oklch(0.48 0.14 20))',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color: 'white', boxShadow: '0 1px 0 rgba(255,255,255,0.3) inset, 0 1px 2px rgba(0,0,0,0.1)',
    }}>
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
        <path d="M12 3c-3 4-6 7-6 11a6 6 0 0012 0c0-4-3-7-6-11z"/>
      </svg>
    </div>
    <div style={{ lineHeight: 1 }}>
      <div style={{ fontSize: 13, fontWeight: 650, letterSpacing: -0.2 }}>Saucecompany</div>
      <div style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: 0.4, fontWeight: 500, marginTop: 2 }}>NPD · ONTWIKKELING</div>
    </div>
  </div>
);

// ─── Sidebar ────────────────────────────────────────────
const Sidebar = ({ view, setView, onNewProject }) => {
  const items = [
    { id: 'kanban', label: 'Kanban', icon: 'kanban', count: 15 },
    { id: 'mijndag', label: 'Mijn dag', icon: 'today', count: 5, hot: true },
    { id: 'klanten', label: 'Per klant', icon: 'klant' },
    { id: 'lijst', label: 'Alle projecten', icon: 'lijst' },
    { id: 'team', label: 'Team workload', icon: 'team' },
  ];
  return (
    <aside style={{
      width: 232, flexShrink: 0, background: 'var(--paper)',
      borderRight: '1px solid var(--line)', display: 'flex', flexDirection: 'column',
      padding: '18px 14px 14px',
    }}>
      <div style={{ padding: '0 6px 18px' }}><Logo /></div>

      <button className="primary-btn" onClick={onNewProject} style={{
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        gap: 8, padding: '10px 12px', borderRadius: 9,
        background: 'var(--ink-1)', color: 'var(--paper)', border: 'none',
        fontSize: 13, fontWeight: 600, cursor: 'pointer', marginBottom: 14,
        boxShadow: '0 1px 0 rgba(255,255,255,0.1) inset, 0 1px 2px rgba(0,0,0,0.06)',
      }}>
        <Icon name="plus" size={14} /> Nieuwe aanvraag
      </button>

      <nav style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
        {items.map(it => (
          <button key={it.id} onClick={() => setView(it.id)} style={{
            display: 'flex', alignItems: 'center', gap: 10,
            padding: '8px 10px', borderRadius: 7,
            border: 'none', background: view === it.id ? 'var(--accent-bg)' : 'transparent',
            color: view === it.id ? 'var(--accent-fg)' : 'var(--ink-2)',
            fontSize: 13, fontWeight: view === it.id ? 600 : 500,
            cursor: 'pointer', textAlign: 'left',
          }}>
            <Icon name={it.icon} size={16} />
            <span style={{ flex: 1 }}>{it.label}</span>
            {it.count != null && (
              <span style={{
                fontSize: 11, fontWeight: 600,
                color: it.hot ? 'oklch(0.98 0 0)' : 'var(--ink-3)',
                background: it.hot ? 'oklch(0.55 0.18 28)' : 'transparent',
                padding: it.hot ? '1px 6px' : '0',
                borderRadius: 10,
              }}>{it.count}</span>
            )}
          </button>
        ))}
      </nav>

      <div style={{ height: 18 }} />
      <div style={{ padding: '0 10px', fontSize: 10, fontWeight: 600, color: 'var(--ink-3)', letterSpacing: 0.6, marginBottom: 6 }}>
        LABELS
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
        {['HAK','Albert Heijn','Unox','Remia','Jumbo','retail','huismerk','food-service'].map(l => (
          <button key={l} style={{
            display: 'flex', alignItems: 'center', gap: 10,
            padding: '6px 10px', borderRadius: 6, border: 'none',
            background: 'transparent', color: 'var(--ink-2)', fontSize: 12,
            cursor: 'pointer', textAlign: 'left',
          }}>
            <span style={{ width: 8, height: 8, borderRadius: 2, background: `oklch(0.70 0.14 ${(l.length * 37) % 360})` }} />
            <span style={{ flex: 1 }}>{l}</span>
          </button>
        ))}
        <button style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '6px 10px', borderRadius: 6, border: 'none',
          background: 'transparent', color: 'var(--ink-3)', fontSize: 12,
          cursor: 'pointer', textAlign: 'left',
        }}>
          <Icon name="plus" size={12} /> Label toevoegen
        </button>
      </div>

      <div style={{ flex: 1 }} />

      <div style={{
        padding: '10px', background: 'var(--surface-1)', borderRadius: 8,
        fontSize: 11, color: 'var(--ink-2)', lineHeight: 1.45,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <Avatar m={window.medewerkerById(window.CURRENT_USER_ID)} size={24} />
          <div>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-1)' }}>Sanne de Vries</div>
            <div style={{ fontSize: 10, color: 'var(--ink-3)' }}>Binnendienst</div>
          </div>
        </div>
      </div>
    </aside>
  );
};

// ─── Topbar ─────────────────────────────────────────────
const Topbar = ({ view, onToggleFilter, search, setSearch }) => {
  const titles = {
    kanban: 'NPD Ontwikkeling',
    mijndag: 'Mijn dag',
    klanten: 'Per klant',
    lijst: 'Alle projecten',
    team: 'Team workload',
  };
  const subtitles = {
    kanban: '15 lopende projecten · 22 buckets',
    mijndag: `${window.getMyTasks(window.CURRENT_USER_ID).length} taken openstaand · zaterdag 18 april`,
    klanten: 'Aanvragen gegroepeerd per klant',
    lijst: 'Zoek, filter en exporteer',
    team: 'Bezetting en doorlooptijden',
  };
  return (
    <header style={{
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '14px 24px', borderBottom: '1px solid var(--line)',
      background: 'var(--paper)',
    }}>
      <div style={{ flex: 1, minWidth: 0 }}>
        <h1 style={{ fontSize: 18, fontWeight: 650, letterSpacing: -0.3, margin: 0 }}>{titles[view]}</h1>
        <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>{subtitles[view]}</div>
      </div>

      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '7px 10px', background: 'var(--surface-1)',
        border: '1px solid var(--line)', borderRadius: 8, width: 260,
        color: 'var(--ink-3)',
      }}>
        <Icon name="search" size={14} />
        <input value={search} onChange={e => setSearch(e.target.value)} placeholder="Zoek project, klant, saus…"
          style={{
            border: 'none', outline: 'none', background: 'transparent',
            fontSize: 13, flex: 1, color: 'var(--ink-1)', fontFamily: 'inherit',
          }} />
        <span style={{ fontSize: 10, color: 'var(--ink-3)', padding: '1px 5px', background: 'var(--paper)', borderRadius: 4, border: '1px solid var(--line)' }}>⌘K</span>
      </div>

      <button onClick={onToggleFilter} style={{
        display: 'flex', alignItems: 'center', gap: 6,
        padding: '7px 12px', border: '1px solid var(--line)',
        borderRadius: 8, background: 'var(--paper)', cursor: 'pointer',
        fontSize: 13, fontWeight: 500, color: 'var(--ink-2)',
      }}>
        <Icon name="filter" size={14} /> Filter
      </button>

      <button style={{
        width: 34, height: 34, borderRadius: 8, border: '1px solid var(--line)',
        background: 'var(--paper)', cursor: 'pointer', color: 'var(--ink-2)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        position: 'relative',
      }}>
        <Icon name="bell" size={16} />
        <span style={{
          position: 'absolute', top: 6, right: 6,
          width: 6, height: 6, borderRadius: '50%',
          background: 'oklch(0.60 0.20 28)',
        }} />
      </button>
    </header>
  );
};

Object.assign(window, {
  Pill, Dot, Avatar, AvatarStack, PrioPill, TeamChip, DeadlineChip,
  Icon, Logo, Sidebar, Topbar, fmtDate, fmtRel, fmtDateLong,
});
