/* Al-Huwais — role-aware application shell */
const ROLE_NAV={
'System Administrator':'*',
'Executive Management':['dashboard','aicos','invoices','receivables','budgeting','contracts','certificates'],
'Lab / Technical Manager':['dashboard','aicos','planning','execution','certificates','standards','uncertainty','environment','traceability','documents','competency','goods-receipt'],
'Calibration Technician':['dashboard','my-jobs','execution','environment','standards','aicos'],
'Quality Manager':['dashboard','aicos','documents','audit','ncr','complaints','risk','management','competency','proficiency','incidents'],
'Sales / Business Development':['dashboard','aicos','customers','leads','quotations','contracts','receiving'],
'Finance Manager':['dashboard','aicos','invoices','receivables','payables','expenses','vat','budgeting'],
'HR Manager':['dashboard','aicos','employees','training','leave','attendance','nitaqat'],
'Warehouse / Store Keeper':['dashboard','goods-receipt','inventory','suppliers','standards'],
'Customer':['portal']};
const NAV_GROUPS=[
{group:'Overview',items:[['dashboard','Dashboard','grid'],['aicos','AI-COS Console','sparkles']]},
{group:'Sales & CRM',items:[['customers','Customers','users'],['leads','Leads','trend'],['quotations','Quotations','receipt'],['contracts','Contracts','documents'],['receiving','Receiving','box'],['delivery','Delivery','truck']]},
{group:'Laboratory',items:[['planning','Planning','calendar'],['my-jobs','My Jobs','briefcase'],['execution','Jobs & Execution','workflow'],['certificates','Certificates','certificate'],['standards','Reference Standards','gauge'],['uncertainty','Uncertainty','chart'],['environment','Environment','thermometer'],['traceability','Traceability','link']]},
{group:'Quality',items:[['ncr','NCR & CAPA','flag'],['complaints','Complaints','chat'],['risk','Risk & Opportunity','shield'],['audit','Internal Audit','check-shield'],['management','Management Review','chart'],['documents','Documents / Methods','documents'],['competency','Competency','users'],['proficiency','Proficiency Testing','flask'],['incidents','HSE Incidents','helmet']]},
{group:'Finance',items:[['invoices','Invoices','receipt'],['receivables','Receivables','trend'],['payables','Payables','receipt'],['expenses','Expenses','briefcase'],['vat','VAT / ZATCA','qr'],['budgeting','Budgeting','chart']]},
{group:'HR',items:[['employees','Employees','users'],['training','Training','certificate'],['leave','Leave','calendar'],['attendance','Attendance','clock'],['nitaqat','Nitaqat','building']]},
{group:'Warehouse',items:[['goods-receipt','Goods Receipt','box'],['inventory','Inventory','box'],['suppliers','Suppliers','truck']]},
{group:'Portal',items:[['portal','Customer Portal','building']]}];
function allowedNav(role){const a=ROLE_NAV[role]||[];return NAV_GROUPS.map(g=>({...g,items:g.items.filter(x=>a==='*'||a.includes(x[0]))})).filter(g=>g.items.length)}
function Sidebar({active,onNav}){const D=window.DB,overdue=D.assets.filter(a=>a.due&&new Date(a.due)<D.TODAY).length,openNcr=D.ncrs.filter(n=>n.stage!=='Closed').length;return <aside className="sidebar"><div className="brand"><span className="brand-mark"><Icon name="gauge" size={20}/></span><div><div className="brand-name">Al-Huwais Maintenance</div><div className="brand-sub">Calibration ERP · LIMS</div></div></div><nav className="nav">{allowedNav(window.ROLE).map(g=><div key={g.group}><div className="nav-group-label">{g.group}</div>{g.items.map(it=><div key={it[0]} className={'nav-item'+(active===it[0]?' active':'')} onClick={()=>onNav(it[0])}><Icon name={it[2]} size={18} className="nav-ico"/><span>{it[1]}</span>{it[0]==='ncr'&&openNcr?<span className="nav-badge amber">{openNcr}</span>:it[0]==='receiving'&&overdue?<span className="nav-badge">{overdue}</span>:null}</div>)}</div>)}</nav><div className="side-foot"><div className="readiness-card" onClick={()=>onNav('dashboard')}><div className="row" style={{justifyContent:'space-between'}}><span style={{fontSize:11,color:'#9fb4d0',fontWeight:700}}>AUDIT READINESS</span><Icon name="shield" size={14}/></div><div style={{fontSize:28,fontWeight:800,color:'#fff',marginTop:6}}>{auditReadiness()}<span style={{fontSize:12,color:'#7e94b0'}}> / 100</span></div></div></div></aside>}
function Topbar({title,onOpenNotif,onOpenAI}){const role=window.ROLE,s=DB.staff.find(x=>x.role===role)||DB.staff[0];return <header className="topbar"><div className="breadcrumb"><span>Al-Huwais</span><Icon name="chevR" size={13}/><b>{title}</b></div><div className="spacer"/><div className="searchbox"><Icon name="search" size={16}/><input placeholder="Search equipment, jobs, certificates…"/><kbd>⌘K</kbd></div><Btn variant="ai" icon="sparkles" onClick={onOpenAI}>Ask AI-COS</Btn><div className="field" style={{minWidth:180}}><select value={role} onChange={e=>{window.ROLE=e.target.value;window.__bump()}} title="Switch demo persona">{DB.roles.map(r=><option key={r}>{r}</option>)}</select></div><button className="icon-btn" onClick={onOpenNotif}><Icon name="bell" size={17}/><span className="dot-badge"/></button><div className="vr"/><Avatar id={s&&s.id}/><div className="col" style={{gap:0}}><b style={{fontSize:12.5}}>{s?s.name:'Demo user'}</b><span className="faint" style={{fontSize:11}}>{role}</span></div></header>}
function MiniAIChart({chart}){if(!chart)return null;const data=chart.data||[],max=Math.max(...data.map(x=>x.n),1),sum=data.reduce((a,x)=>a+x.n,0)||1;if(chart.type==='donut'){let off=0,C=2*Math.PI*34;return <div className="row"><svg viewBox="0 0 90 90" style={{width:110}}><circle cx="45" cy="45" r="34" fill="none" stroke="var(--border)" strokeWidth="12"/>{data.map((d,i)=>{const n=d.n/sum*C,e=<circle key={d.k} cx="45" cy="45" r="34" fill="none" stroke={['#2f6fed','#15a06b','#c9820a'][i%3]} strokeWidth="12" strokeDasharray={`${n} ${C-n}`} strokeDashoffset={-off} transform="rotate(-90 45 45)"/>;off+=n;return e})}</svg><div>{data.map(d=><div key={d.k} className="row" style={{fontSize:12}}><span style={{width:110}}>{d.k}</span><b>{d.n}</b></div>)}</div></div>}return <div style={{display:'flex',height:120,alignItems:'flex-end',gap:8}}>{data.map(d=><div key={d.k} style={{flex:1,textAlign:'center'}}><div className="mono" style={{fontSize:9}}>{Number(d.n).toLocaleString()}</div><div style={{height:Math.max(4,d.n/max*80),background:'var(--ai)',borderRadius:'4px 4px 0 0'}}/><span className="faint" style={{fontSize:9}}>{d.k}</span></div>)}</div>}
function AIConversation({compact=false}){const suggested=DB.aicosSuggestions.filter(x=>!x.role||x.role===window.ROLE),[messages,setMessages]=useState([]),[q,setQ]=useState('');const ask=text=>{if(!text)return;const answer=window.aicosAnswer(text);setMessages(s=>[...s,{q:text,a:answer}]);setQ('')};return <div><div className="wrap" style={{gap:7,marginBottom:14}}>{suggested.slice(0,compact?5:9).map((x,i)=><Btn key={i} size="sm" variant="ai" onClick={()=>ask(x.q)}>{x.q}</Btn>)}</div>{messages.map((m,i)=><div key={i} className="card card-pad" style={{marginBottom:12}}><div className="cell-sub">You</div><b>{m.q}</b><div className="divider"/><div className="row" style={{alignItems:'flex-start'}}><span className="ai-badge-ico"><Icon name="sparkles" fill size={14}/></span><div style={{flex:1}}><div>{m.a.text}</div><MiniAIChart chart={m.a.chart}/>{m.a.table&&<div style={{overflowX:'auto',marginTop:10}}><table className="tbl"><thead><tr>{Object.keys(m.a.table[0]||{}).map(k=><th key={k}>{k}</th>)}</tr></thead><tbody>{m.a.table.slice(0,8).map((r,ri)=><tr key={ri}>{Object.keys(r).map(k=><td key={k}>{r[k]}</td>)}</tr>)}</tbody></table></div>}<div className="faint" style={{fontSize:10.5,marginTop:8}}>Sources: {(m.a.cites||[]).join(' · ')}</div>{m.a.action&&<Btn size="sm" variant="ai" style={{marginTop:9}} onClick={()=>toast(m.a.action.note,'ai')}>{m.a.action.label}</Btn>}</div></div></div>)}<form className="row" onSubmit={e=>{e.preventDefault();ask(q)}}><input className="input" value={q} onChange={e=>setQ(e.target.value)} placeholder="Ask a question about live ERP/LIMS data…"/><Btn variant="primary" icon="arrowR">Ask</Btn></form></div>}
function AICOSPanel({open,onClose}){return <Drawer open={open} onClose={onClose} width={720}><div className="drawer-head"><span className="ai-badge-ico"><Icon name="sparkles" fill/></span><div style={{flex:1}}><b>AI-COS · AI Business Intelligence</b><div className="faint" style={{fontSize:11}}>Advisory only · cites its sources · respects your role permissions · never acts without your confirmation</div></div><button className="icon-btn" onClick={onClose}><Icon name="x"/></button></div><div className="drawer-body"><div style={{display:'grid',gridTemplateColumns:'repeat(3,1fr)',gap:10,marginBottom:16}}>{DB.aicosInsights.map((x,i)=><div className="card card-pad" key={i}><Icon name={x.icon} style={{color:'var(--ai)'}}/><b style={{display:'block',marginTop:7}}>{x.title}</b><div className="faint" style={{fontSize:11}}>{x.detail}</div></div>)}</div><AIConversation compact/></div></Drawer>}
function notificationItems(){const out=[];DB.standards.filter(x=>x.due&&(new Date(x.due)-DB.TODAY)/864e5<=30).forEach(x=>out.push(['gauge','warn',x.id+' standard due',DB.rel(new Date(x.due)),'standards']));DB.jobs.filter(x=>x.due&&new Date(x.due)<DB.TODAY&&!['Delivered','Certified'].includes(x.stage)).forEach(x=>out.push(['clock','bad',x.id+' is overdue',DB.rel(new Date(x.due)),'execution']));return out}
function NotifPanel({open,onClose,onNav}){const items=notificationItems();return <Drawer open={open} onClose={onClose} width={410}><div className="drawer-head"><Icon name="bell"/><b style={{flex:1}}>Lab notifications</b><button className="icon-btn" onClick={onClose}><Icon name="x"/></button></div><div className="drawer-body">{items.length?items.map((x,i)=><div className="lrow" key={i} style={{cursor:'pointer'}} onClick={()=>{onClose();onNav(x[4])}}><span className="kpi-ico"><Icon name={x[0]} size={16}/></span><div><b>{x[2]}</b><div className="faint" style={{fontSize:12}}>{x[3]}</div></div></div>):<EmptyState icon="check-circle" title="All clear" desc="No alerts need attention."/>}</div></Drawer>}
Object.assign(window,{Sidebar,Topbar,NotifPanel,AICOSPanel,AIConversation,MiniAIChart,NAV_GROUPS,ROLE_NAV,allowedNav});
