/* ============================================================
   Shared UI components -> window
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;
const Icon = window.Icon;

/* ---- status meta ---- */
const STATUS = {
  completed:   { label:'Completed',   cls:'ok' },
  in_progress: { label:'In progress', cls:'info' },
  not_started: { label:'Not started', cls:'neutral' },
  overdue:     { label:'Overdue',     cls:'danger' },
  failed:      { label:'Failed',      cls:'warn' },
  available:   { label:'Available',   cls:'neutral' },
  published:   { label:'Published',   cls:'ok' },
  draft:       { label:'Draft',       cls:'warn' },
  superseded:  { label:'Superseded',  cls:'neutral' },
};

function Badge({ status, children, cls }) {
  const m = STATUS[status];
  const c = cls || (m && m.cls) || 'neutral';
  return (
    <span className={'badge ' + c}>
      <span className="bdot"></span>{children || (m && m.label) || status}
    </span>
  );
}

function Avatar({ name, color, initials, size='av-md' }) {
  const ini = initials || (name||'?').split(' ').map(w=>w[0]).slice(0,2).join('').toUpperCase();
  return <span className={'avatar '+size} style={{ background: color || '#2E6CD6' }}>{ini}</span>;
}

function Swatch({ course, size=44, font=16, radius }) {
  return (
    <span className="swatch" style={{ width:size, height:size, fontSize:font, background:course.color, borderRadius: radius||'8px' }}>
      {course.abbr}
    </span>
  );
}

function Progress({ value, thin }) {
  return <div className={'pbar'+(thin?' thin':'')}><span style={{ width: Math.max(0,Math.min(100,value))+'%' }}></span></div>;
}
function ProgressMini({ value }) {
  return (
    <div className="pmini">
      <Progress value={value} thin />
      <span className="num">{value}%</span>
    </div>
  );
}

function StatCard({ icon, iconBg, iconColor, label, value, unit, sub, trend, trendDir }) {
  return (
    <div className="stat">
      <div className="stat-top">
        <span className="stat-label">{label}</span>
        {icon && <span className="stat-ic" style={{ background:iconBg||'var(--info-bg)', color:iconColor||'var(--brand)' }}><Icon n={icon} size={18} /></span>}
      </div>
      <div className="stat-value">{value}{unit && <em> {unit}</em>}</div>
      {(sub||trend) && (
        <div className="stat-sub">
          {trend && <span className={'trend '+(trendDir||'up')}><Icon n={trendDir==='down'?'arrowl':'trend'} size={12} />{trend}</span>}
          {sub && <span>{sub}</span>}
        </div>
      )}
    </div>
  );
}

/* Donut chart (svg) — segments: [{value, color, label}] */
function Donut({ segments, size=150, stroke=20, centerVal, centerLbl }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const total = segments.reduce((s,x)=>s+x.value,0) || 1;
  let offset = 0;
  return (
    <div className="donut-wrap" style={{ width:size, height:size }}>
      <svg width={size} height={size} style={{ transform:'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--surface-3)" strokeWidth={stroke} />
        {segments.map((s,i)=>{
          const len = (s.value/total)*c;
          const el = <circle key={i} cx={size/2} cy={size/2} r={r} fill="none" stroke={s.color} strokeWidth={stroke}
            strokeDasharray={`${len} ${c-len}`} strokeDashoffset={-offset} strokeLinecap="butt" />;
          offset += len;
          return el;
        })}
      </svg>
      {(centerVal!=null) && (
        <div className="donut-center">
          <div className="dc-val">{centerVal}</div>
          {centerLbl && <div className="dc-lbl">{centerLbl}</div>}
        </div>
      )}
    </div>
  );
}

/* Bar chart — data: number[] (0-100), accentLast highlights final bar */
function BarChart({ data, height=120, labels }) {
  const max = Math.max(...data, 1);
  return (
    <div>
      <div style={{ display:'flex', alignItems:'flex-end', gap:6, height }}>
        {data.map((d,i)=>(
          <div key={i} style={{ flex:1, display:'flex', flexDirection:'column', justifyContent:'flex-end', height:'100%' }}>
            <div style={{
              height: (d/max*100)+'%',
              background: i===data.length-1 ? 'var(--grad)' : 'var(--surface-3)',
              borderRadius:'4px 4px 0 0', minHeight:3, transition:'height .4s'
            }}></div>
          </div>
        ))}
      </div>
      {labels && <div style={{ display:'flex', gap:6, marginTop:8 }}>
        {labels.map((l,i)=><div key={i} className="lbl" style={{ flex:1, textAlign:'center', fontSize:8.5 }}>{l}</div>)}
      </div>}
    </div>
  );
}

/* Modal */
function Modal({ title, kicker, onClose, children, footer, wide }) {
  useEffect(()=>{
    const h = e => { if (e.key==='Escape') onClose(); };
    window.addEventListener('keydown', h);
    return ()=>window.removeEventListener('keydown', h);
  },[]);
  return (
    <div className="overlay" onClick={onClose}>
      <div className={'modal'+(wide?' wide':'')} onClick={e=>e.stopPropagation()}>
        <div className="modal-head">
          <div>
            {kicker && <div className="kicker" style={{ marginBottom:5 }}>{kicker}</div>}
            <div className="h-sec">{title}</div>
          </div>
          <button className="icon-btn" style={{ width:34, height:34, border:0, background:'var(--surface-2)' }} onClick={onClose}><Icon n="x" size={17} /></button>
        </div>
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-foot">{footer}</div>}
      </div>
    </div>
  );
}

/* Toast */
function Toast({ msg, onDone }) {
  useEffect(()=>{ const t=setTimeout(onDone, 2800); return ()=>clearTimeout(t); },[]);
  return (
    <div style={{ position:'fixed', bottom:26, left:'50%', transform:'translateX(-50%)', zIndex:200,
      background:'var(--navy)', color:'#fff', padding:'13px 20px', borderRadius:'10px', boxShadow:'var(--shadow-lg)',
      display:'flex', alignItems:'center', gap:10, fontSize:14, fontWeight:500, animation:'pop .25s ease' }}>
      <span style={{ color:'var(--sky)', display:'grid', placeItems:'center' }}><Icon n="checkc" size={18} /></span>
      {msg}
    </div>
  );
}

/* Sidebar */
function Sidebar({ roleName, roleSub, nav, active, onNav, user }) {
  return (
    <aside className="sidebar">
      <div className="side-head">
        <div className="role-name">{roleName}</div>
        <div className="role-sub">{roleSub}</div>
      </div>
      <nav className="nav">
        {nav.map((item,i)=> item.section
          ? <div key={i} className="nav-section">{item.section}</div>
          : <button key={item.id} className={'nav-item'+(active===item.id?' active':'')} onClick={()=>onNav(item.id)}>
              <Icon n={item.icon} />
              <span>{item.label}</span>
              {item.count!=null && <span className="badge-count">{item.count}</span>}
            </button>
        )}
      </nav>
      <div className="side-foot">
        <div className="side-user">
          <Avatar name={user.name} color={user.color} size="av-sm" />
          <div style={{ minWidth:0 }}>
            <div className="u-name">{user.name}</div>
            <div className="u-role">{user.role}</div>
          </div>
          <button className="icon-btn" style={{ width:30, height:30, marginLeft:'auto', border:0, background:'transparent', color:'var(--side-faint)' }}><Icon n="logout" size={16} /></button>
        </div>
      </div>
    </aside>
  );
}

/* Topbar */
function Topbar({ crumb, title, searchPlaceholder, actions }) {
  return (
    <header className="topbar">
      <div>
        {crumb && <div className="page-crumb">{crumb}</div>}
        <div className="page-title">{title}</div>
      </div>
      <div className="spacer"></div>
      {actions}
    </header>
  );
}

/* Section header */
function SectionHead({ kicker, title, children }) {
  return (
    <div className="section-head">
      <div>
        {kicker && <div className="kicker" style={{ marginBottom:6 }}>{kicker}</div>}
        <h2 className="h-sec">{title}</h2>
      </div>
      {children && <div className="row gap8">{children}</div>}
    </div>
  );
}

Object.assign(window, {
  STATUS, Badge, Avatar, Swatch, Progress, ProgressMini, StatCard,
  Donut, BarChart, Modal, Toast, Sidebar, Topbar, SectionHead, Icon
});
