// evaluation-cmmi-engine.jsx — Verigo Global: CMMI v2.0 readiness evaluation engine
// Target Maturity Level chosen in scope decides which practice areas are assessed.
// Exposes window.EVAL_CMMI
const { V: GV, MAXW: GMW, FONT: GFT } = window;

// Build PA→icon lookup from CMMI_CATS global (loaded first by data file)
const CMMI_PA_ICONS = {};
(function(){ CMMI_CATS.forEach(c => c.pas.forEach(p => { CMMI_PA_ICONS[p.code] = c.icon; })); })();

/* ── QUESTION BANK — 20 practice areas × 2 questions each ── */
const CMMI_Q = [
  { code:'EST', name:'Estimating', ml2:true, docs:['Estimating & Planning Policy','Project Estimating Procedure'], q:[
    ['EST 1.1','Estimates of work product size, effort, and cost are established and recorded.'],['EST 2.1','Estimates are reconciled with actual data and updated throughout the project.'],
  ]},
  { code:'PLAN', name:'Planning', ml2:true, docs:['Estimating & Planning Policy','Project Planning Procedure'], q:[
    ['PLAN 1.1','A project plan is established, documenting milestones, resources, and commitments.'],['PLAN 2.2','The plan is maintained and reconciled with available resources.'],
  ]},
  { code:'MC', name:'Monitor and Control', ml2:true, docs:['Project Monitoring & Control Policy','Monitor & Control Procedure'], q:[
    ['MC 1.1','Project performance is monitored against the plan at defined intervals.'],['MC 1.2','Corrective actions are taken and managed to closure when actual performance deviates from the plan.'],
  ]},
  { code:'SAM', name:'Supplier Agreement Management', ml2:true, docs:['Supplier Agreement Management Policy','Supplier Evaluation & Agreement Procedure'], q:[
    ['SAM 1.1','Formal supplier agreements define requirements, delivery, acceptance, and review criteria.'],['SAM 1.2','Supplier performance is monitored against agreements.'],
  ]},
  { code:'RDM', name:'Requirements Development & Management', ml2:true, docs:['Requirements Management Policy','Requirements Development & Management Procedure'], q:[
    ['RDM 1.1','Requirements are elicited, developed, analyzed, and recorded.'],['RDM 1.2','Requirements are traced bidirectionally throughout the project lifecycle.'],
  ]},
  { code:'PQA', name:'Process Quality Assurance', ml2:true, docs:['Process Quality Assurance Policy','Quality Assurance Review Procedure'], q:[
    ['PQA 1.1','Adherence of performed processes to applicable plans and standards is objectively evaluated.'],['PQA 2.1','Noncompliance issues are communicated and resolved.'],
  ]},
  { code:'CM', name:'Configuration Management', ml2:true, docs:['Configuration Management Policy','Configuration Management Procedure'], q:[
    ['CM 1.1','Configuration items are identified and baselines are established.'],['CM 2.1','Changes to configuration items are tracked and controlled; audits are conducted.'],
  ]},
  { code:'MA', name:'Measurement and Analysis', ml2:true, docs:['Measurement & Analysis Policy','Measurement Data Collection Procedure'], q:[
    ['MA 1.1','Measurement objectives and measures are established aligned to information needs.'],['MA 2.1','Measurement data is collected, stored, analyzed, and reported.'],
  ]},
  { code:'GOV', name:'Governance', ml2:true, docs:['Process Management Policy'], q:[
    ['GOV 1.1','Senior management commitment to CMMI processes is demonstrated and sustained.'],['GOV 1.2','Policies guide CMMI implementation across the organization.'],
  ]},
  { code:'II', name:'Implementation Infrastructure', ml2:true, docs:['Process Management Policy'], q:[
    ['II 1.1','Resources, roles, and repositories needed for process implementation are identified and provided.'],['II 2.1','Process support and guidance is accessible to practitioners.'],
  ]},
  { code:'VV', name:'Verification and Validation', ml2:false, docs:['Verification & Validation Policy'], q:[
    ['VV 1.1','Work products selected for verification are reviewed against requirements.'],['VV 2.2','Validation confirms that products meet their intended use in the target environment.'],
  ]},
  { code:'TS', name:'Technical Solution', ml2:false, docs:['Technical Solution Policy'], q:[
    ['TS 1.1','Technical solutions are selected and the product is designed to satisfy requirements.'],['TS 2.1','The design is implemented and integrated into a deliverable product or component.'],
  ]},
  { code:'PI', name:'Product Integration', ml2:false, docs:['Process Management Policy'], q:[
    ['PI 1.1','Product integration preparation ensures interface compatibility and integration sequences are defined.'],['PI 2.1','Product components are assembled and the integrated product is delivered.'],
  ]},
  { code:'PR', name:'Peer Reviews', ml2:false, docs:['Peer Review Policy','Peer Review Procedure'], q:[
    ['PR 1.1','Peer reviews are prepared with checklists, roles, and entry/exit criteria.'],['PR 2.1','Peer review data is analyzed and used to improve the work product and process.'],
  ]},
  { code:'PCM', name:'Process Management', ml2:false, docs:['Process Management Policy'], q:[
    ['PCM 1.1',"Organizational process needs are established and process performance baselines are maintained."],['PCM 2.2','The performance of the organization\'s processes is continuously monitored.'],
  ]},
  { code:'OT', name:'Organizational Training', ml2:false, docs:['Process Management Policy'], q:[
    ['OT 1.1','Skills needed for assigned roles are identified and training plans are established.'],['OT 2.1','Training effectiveness is assessed and training records are maintained.'],
  ]},
  { code:'DAR', name:'Decision Analysis and Resolution', ml2:false, docs:['Decision Analysis & Resolution Policy'], q:[
    ['DAR 1.1','Formal evaluation criteria are established for significant decisions.'],['DAR 2.1','Alternative solutions are evaluated against criteria and decisions are documented.'],
  ]},
  { code:'RSK', name:'Risk and Opportunity Management', ml2:false, docs:['Risk & Opportunity Management Policy','Risk & Opportunity Management Procedure'], q:[
    ['RSK 1.1','Risks are identified, categorized, and prioritized.'],['RSK 2.1','Risk mitigation plans are developed, implemented, and monitored.'],
  ]},
  { code:'PAD', name:'Process Asset Development', ml2:false, docs:['Process Management Policy','Process Improvement Proposal Procedure'], q:[
    ['PAD 1.1','Organizational process assets are established and maintained in a library.'],['PAD 2.1','Process improvement proposals are gathered, reviewed, and implemented.'],
  ]},
  { code:'MPM', name:'Managing Performance and Measurement', ml2:false, docs:['Measurement & Analysis Policy'], q:[
    ['MPM 1.1','Performance baselines and models are established to support quantitative management.'],['MPM 2.1','Performance data is used to manage selected processes quantitatively.'],
  ]},
  { code:'CAR', name:'Causal Analysis and Resolution', ml2:false, docs:['Causal Analysis & Resolution Policy','Causal Analysis & Resolution Procedure'], q:[
    ['CAR 1.1','Causes of defects and problems are identified and analyzed.'],['CAR 2.1','Corrective actions are implemented and their effect on process performance is evaluated.'],
  ]},
];

const CMMI_ML_LABELS = { ml2:'ML2 · Managed', ml3:'ML3 · Defined', ml45:'ML4/5 · Quantitative' };

function mSectionsForML(ml) {
  const lv = (ml === 'ml2' || ml === 'ml3' || ml === 'ml45') ? ml : 'ml3';
  const grp = CMMI_ML_LABELS[lv];
  const list = lv === 'ml2' ? CMMI_Q.filter(p => p.ml2) : CMMI_Q;
  return list.map(p => ({ code: p.code, theme: p.code + ' · ' + p.name, group: grp, icon: CMMI_PA_ICONS[p.code] || 'layers', docs: p.docs, controls: (CMMI_CATS.find(c=>c.pas.find(pa=>pa.code===p.code))?.pas.find(pa=>pa.code===p.code)?.items.length||3), q: p.q }));
}

const COPTIONS = [['Not started',0],['Partial',1],['Largely',2],['Fully',3]];
const CBANDS = [
  [0,'Initial',GV.orange,'Process activities are ad hoc — start with the ML2 essentials.'],
  [40,'Developing',GV.orange,'Some practices exist but key ML2 areas have gaps.'],
  [60,'Managed',GV.purple,'ML2 baseline is largely in place — focus on the remaining gaps.'],
  [80,'Defined',GV.purple,'Strong posture — formalize remaining practices and evidence for appraisal.'],
];
const cBandFor = pct => { let b=CBANDS[0]; CBANDS.forEach(x=>{ if(pct>=x[0]) b=x; }); return b; };

function mCompute(answers, sections) {
  const secs = sections || mSectionsForML('ml3');
  const themes = secs.map((t,ti)=>{ const max=t.q.length*3; let sum=0; t.q.forEach((_,qi)=>{ sum+=(answers[ti+'-'+qi]||0); }); const pct=Math.round((sum/max)*100); return { theme:t.theme, code:t.code, group:t.group, icon:t.icon, docs:t.docs, controls:t.controls, pct, gaps:Math.round((1-pct/100)*t.controls) }; });
  const overall=themes.length?Math.round(themes.reduce((a,t)=>a+t.pct,0)/themes.length):0;
  const totalControls=secs.reduce((a,t)=>a+t.controls,0);
  const gaps=themes.reduce((a,t)=>a+t.gaps,0);
  return { themes, overall, gaps, totalControls, level:(secs[0]&&secs[0].group)||CMMI_ML_LABELS.ml3, band:cBandFor(overall) };
}

/* ── SEGMENTED ────────────────────────────────────────────── */
const MSegmented = ({ value, onChange }) => (
  <div style={{display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:6}}>
    {COPTIONS.map(([label,val])=>{ const on=value===val; return <button key={val} type="button" onClick={()=>onChange(val)} style={{fontFamily:GFT,fontSize:13,fontWeight:700,padding:'10px 6px',cursor:'pointer',textAlign:'center',background:on?GV.purple:'#fff',color:on?'#fff':GV.g600,border:`1.5px solid ${on?GV.purple:GV.g200}`,transition:'all 120ms'}}>{label}</button>; })}
  </div>
);

/* ── QUIZ ────────────────────────────────────────────────── */
const EvalQuizCMMI = ({ onComplete, onExit, ml, initialAnswers, initialStep, onProgress }) => {
  const sections = React.useMemo(()=>mSectionsForML(ml),[ml]);
  const [step,setStep] = React.useState(()=>Math.min(Math.max(initialStep||0,0),sections.length-1));
  const [answers,setAnswers] = React.useState(()=>initialAnswers||{});
  const total=sections.length; const cur=sections[step];
  const report=(a,s)=>{ if(onProgress) onProgress(a,s); };
  const set=(qi,v)=>setAnswers(a=>{ const na={...a,[step+'-'+qi]:v}; report(na,step); return na; });
  const stepDone=cur.q.every((_,qi)=>answers[step+'-'+qi]!==undefined);
  const answeredCount=Object.keys(answers).length;
  const totalQ=sections.reduce((a,t)=>a+t.q.length,0);
  const progress=Math.round((answeredCount/totalQ)*100);
  const next=()=>{ if(step<total-1){const ns=step+1;setStep(ns);report(answers,ns);window.scrollTo({top:0});}else{onComplete(mCompute(answers,sections));} };
  const back=()=>{ if(step>0){const ns=step-1;setStep(ns);report(answers,ns);window.scrollTo({top:0});}else{onExit();} };
  return (
    <window.Section bg={GV.g50} pad="48px 0 96px">
      <div style={{maxWidth:820,margin:'0 auto'}}>
        <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:12}}>
          <span style={{fontSize:12,fontWeight:700,letterSpacing:'0.08em',textTransform:'uppercase',color:GV.g400}}>Practice area {step+1} of {total}</span>
          <span style={{fontSize:12,fontWeight:700,color:GV.purple,fontFamily:"'JetBrains Mono',monospace"}}>{progress}% complete</span>
        </div>
        <div style={{height:6,background:GV.g200,marginBottom:28,overflow:'hidden'}}><div style={{width:progress+'%',height:'100%',background:GV.purple,transition:'width 200ms'}}></div></div>
        <div style={{background:'#fff',border:`1px solid ${GV.g200}`,padding:'32px 36px 36px'}}>
          <div style={{display:'flex',alignItems:'center',gap:12,marginBottom:8}}>
            <div style={{width:42,height:42,background:GV.purpleSubtle,color:GV.purple,display:'flex',alignItems:'center',justifyContent:'center'}}><window.Icon name={cur.icon} size={22} /></div>
            <div>
              <div style={{fontSize:11,fontWeight:700,letterSpacing:'0.08em',textTransform:'uppercase',color:GV.g400}}>{cur.group}</div>
              <h2 style={{fontSize:22,fontWeight:800,color:GV.black,margin:0,fontFamily:GFT,letterSpacing:'-0.02em'}}>{cur.theme}</h2>
            </div>
          </div>
          <p style={{fontSize:13.5,color:GV.g500,margin:'0 0 24px',lineHeight:1.55}}>For each statement, choose how completely it reflects your organization today. Each maps to a specific CMMI v2.0 practice.</p>
          <div style={{display:'flex',flexDirection:'column',gap:22}}>
            {cur.q.map(([code,text],qi)=>(
              <div key={qi} style={{borderTop:qi?`1px solid ${GV.g100}`:'none',paddingTop:qi?22:0}}>
                <div style={{display:'flex',gap:12,marginBottom:12}}>
                  <span style={{fontFamily:"'JetBrains Mono',monospace",fontSize:12,fontWeight:700,color:GV.orange,flexShrink:0,marginTop:2,minWidth:44}}>{code}</span>
                  <p style={{fontSize:15.5,fontWeight:600,color:GV.g800,margin:0,lineHeight:1.5}}>{text}</p>
                </div>
                <div style={{paddingLeft:56}}><MSegmented value={answers[step+'-'+qi]} onChange={v=>set(qi,v)} /></div>
              </div>
            ))}
          </div>
        </div>
        <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginTop:24}}>
          <window.Btn kind="ghost" onClick={back}>{step===0?'Exit':'Back'}</window.Btn>
          <window.Btn kind="primary" onClick={next} style={{opacity:stepDone?1:0.45,pointerEvents:stepDone?'auto':'none'}}>{step===total-1?'See my results':'Next practice area'} <window.Icon name="arrow" size={16} color="#fff" /></window.Btn>
        </div>
        {!stepDone&&<p style={{textAlign:'right',fontSize:12.5,color:GV.g400,marginTop:10}}>Answer all {cur.q.length} statements to continue.</p>}
        <div style={{display:'flex',alignItems:'center',gap:8,marginTop:14,fontSize:12.5,color:GV.g400}}><window.Icon name="refresh" size={14} color={GV.g400} /> Your progress is saved automatically — you can leave and resume later.</div>
      </div>
    </window.Section>
  );
};

/* ── RESULTS ─────────────────────────────────────────────── */
const MDonut = ({ pct }) => (
  <div style={{width:168,height:168,borderRadius:'50%',background:`conic-gradient(#fff 0% ${pct}%, rgba(255,255,255,0.2) ${pct}% 100%)`,display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
    <div style={{width:128,height:128,borderRadius:'50%',background:'#fff',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center'}}>
      <span style={{fontSize:48,fontWeight:800,color:GV.black,fontFamily:GFT,letterSpacing:'-0.03em',lineHeight:1}}>{pct}</span>
      <span style={{fontSize:11,fontWeight:700,letterSpacing:'0.08em',textTransform:'uppercase',color:GV.g400,marginTop:4}}>/ 100</span>
    </div>
  </div>
);

const EvalResultsCMMI = ({ results, user, onNav, onRetake }) => {
  const { themes, overall, gaps, band, totalControls, level } = results;
  const [,label,,bandDesc] = band;
  const sorted = [...themes].sort((a,b)=>a.pct-b.pct);
  const focus = sorted.filter(t=>t.pct<80);
  const MODULES = window.TK_CMMI.QUOTE_MODULES;
  const reco = new Set(['tailor']);
  if (overall<80) reco.add('guidance');
  if (overall<60) { reco.add('impl'); reco.add('appraisal'); }
  themes.forEach(t=>{ if(t.pct<60&&(t.code==='MA'||t.code==='GOV'||t.code==='PCM')) reco.add('workshop'); });
  const recoModules = MODULES.filter(m=>reco.has(m.id));
  const goBuild = () => { try{localStorage.setItem('verigo_reco_cmmi',JSON.stringify([...reco]));}catch(e){} onNav('checkout'); };
  return (
    <div>
      <section style={{background:GV.purpleDark,position:'relative',overflow:'hidden'}}>
        <window.GeoWatermark color={GV.orange} style={{top:-40,right:40,width:360,height:340,opacity:0.16}} />
        <div style={{position:'relative',zIndex:1,maxWidth:GMW,margin:'0 auto',padding:'56px 32px 60px'}}>
          <div style={{display:'inline-flex',alignItems:'center',gap:8,background:'rgba(255,255,255,0.12)',color:'#fff',fontSize:11,fontWeight:700,letterSpacing:'0.1em',textTransform:'uppercase',padding:'6px 13px',marginBottom:24}}><window.Icon name="gauge" size={14} color="#fff" /> Your readiness report · {level}</div>
          <div style={{display:'grid',gridTemplateColumns:'168px 1fr',gap:40,alignItems:'center'}}>
            <MDonut pct={overall} />
            <div>
              <div style={{fontSize:13,fontWeight:700,letterSpacing:'0.08em',textTransform:'uppercase',color:'rgba(255,255,255,0.6)',marginBottom:8}}>Overall maturity · {label}</div>
              <h1 className="vg-hero-title" style={{fontSize:38,fontWeight:800,color:'#fff',letterSpacing:'-0.03em',lineHeight:1.1,margin:'0 0 14px',fontFamily:GFT}}>{overall>=80?"You're close to appraisal-ready.":overall>=60?"A solid base, with clear gaps to close.":"There's real groundwork to do first."}</h1>
              <p style={{fontSize:16,color:'rgba(255,255,255,0.7)',lineHeight:1.6,margin:0,maxWidth:600}}>{bandDesc} We estimate <strong style={{color:'#fff'}}>~{gaps} of {totalControls} practices</strong> need attention before your appraisal.{user&&user.company?' Prepared for '+user.company:''}</p>
            </div>
          </div>
        </div>
      </section>
      <window.Section bg="#fff" pad="72px 0 64px">
        <window.SectionHeader overline="By practice area" align="left" title="Where you stand across CMMI" sub="Your maturity in each in-scope practice area, scored from your answers." maxSub={620} />
        <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'28px 56px'}}>
          {themes.map((t,i)=>{ const c=t.pct<60?GV.orange:GV.purple; return(
            <div key={i}>
              <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:8}}>
                <span style={{display:'flex',alignItems:'center',gap:10,fontSize:14.5,fontWeight:700,color:GV.g800,fontFamily:GFT}}><window.Icon name={t.icon} size={18} color={GV.purple} />{t.theme}</span>
                <span style={{fontSize:15,fontWeight:800,color:c,fontFamily:"'JetBrains Mono',monospace"}}>{t.pct}%</span>
              </div>
              <div style={{height:9,background:GV.g100,overflow:'hidden'}}><div style={{width:t.pct+'%',height:'100%',background:c,transition:'width 400ms'}}></div></div>
              <div style={{fontSize:12.5,color:GV.g500,marginTop:7}}>~{t.gaps} of {t.controls} practices need attention</div>
            </div>
          ); })}
        </div>
      </window.Section>
      <window.Section bg={GV.g50} pad="64px 0 72px">
        <window.SectionHeader overline="Your next steps" align="left" title="A plan mapped straight to the toolkit" sub="Start with your weakest practice areas. Each links to the toolkit documents that close the gap fastest." maxSub={640} />
        <div style={{display:'flex',flexDirection:'column',gap:14}}>
          {focus.length===0&&(<div style={{background:'#fff',border:`1px solid ${GV.g200}`,padding:'24px 28px',display:'flex',alignItems:'center',gap:14}}><window.Icon name="check" size={24} color={GV.purple} /><div style={{fontSize:15.5,fontWeight:600,color:GV.g800}}>Every practice area scored 80%+ — you're in strong shape. A practitioner can help validate evidence and prepare for appraisal.</div></div>)}
          {focus.map((t,i)=>(
            <div key={i} style={{background:'#fff',border:`1px solid ${GV.g200}`,padding:'24px 28px',display:'grid',gridTemplateColumns:'44px 1fr auto',gap:20,alignItems:'center'}}>
              <div style={{width:44,height:44,background:GV.purpleSubtle,color:GV.purple,display:'flex',alignItems:'center',justifyContent:'center',fontFamily:"'JetBrains Mono',monospace",fontSize:16,fontWeight:800}}>{i+1}</div>
              <div>
                <div style={{display:'flex',alignItems:'center',gap:10,marginBottom:6}}>
                  <h3 style={{fontSize:16.5,fontWeight:700,color:GV.black,margin:0,fontFamily:GFT}}>{t.theme}</h3>
                  <span style={{fontSize:11,fontWeight:700,padding:'3px 9px',background:t.pct<60?GV.orangeSubtle:GV.purpleSubtle,color:t.pct<60?GV.orange:GV.purple,fontFamily:"'JetBrains Mono',monospace"}}>{t.pct}%</span>
                </div>
                <div style={{display:'flex',flexWrap:'wrap',gap:8}}>{t.docs.map((d,di)=>(<span key={di} style={{display:'inline-flex',alignItems:'center',gap:7,fontSize:13,fontWeight:600,color:GV.g700,background:GV.g50,border:`1px solid ${GV.g200}`,padding:'6px 11px'}}><window.Icon name="doc" size={14} color={GV.purple} />{d}</span>))}</div>
              </div>
              <window.Btn kind="ghostBrand" onClick={()=>onNav('toolkit:cmmi')} style={{whiteSpace:'nowrap'}}>Open toolkit <window.Icon name="arrow" size={15} color={GV.purple} /></window.Btn>
            </div>
          ))}
        </div>
        <div style={{display:'flex',gap:12,flexWrap:'wrap',marginTop:32}}>
          <window.Btn kind="primary" onClick={()=>window.EVAL_CMMI.generateEvalPDF(results,user)}><window.Icon name="doc" size={16} color="#fff" /> Download my results (PDF)</window.Btn>
          <window.Btn kind="ghost" onClick={onRetake}>Retake the evaluation</window.Btn>
        </div>
      </window.Section>
      <window.Section bg="#fff" pad="72px 0 64px">
        <window.SectionHeader overline="Recommended next step" align="left" title="Build a package that closes your gaps" sub="Based on your results we've pre-selected the options most likely to close your gaps fastest." maxSub={680} />
        <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:14,marginBottom:28}}>
          {recoModules.map((m,i)=>(
            <div key={i} style={{display:'flex',gap:14,alignItems:'flex-start',border:`1px solid ${GV.g200}`,padding:'18px 20px'}}>
              <div style={{width:38,height:38,background:GV.purpleSubtle,color:GV.purple,display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}><window.Icon name="check" size={20} color={GV.purple} /></div>
              <div><div style={{fontSize:15,fontWeight:700,color:GV.black,fontFamily:GFT}}>{m.name}</div><div style={{fontSize:13,color:GV.g500,lineHeight:1.5,marginTop:3}}>{m.desc}</div></div>
            </div>
          ))}
        </div>
        <div style={{display:'flex',alignItems:'center',gap:16,flexWrap:'wrap'}}>
          <window.Btn kind="primary" onClick={goBuild}>Build my custom package <window.Icon name="arrow" size={16} color="#fff" /></window.Btn>
          <span style={{fontSize:13,color:GV.g500}}>Pick your options, see the price, then download a custom quote.</span>
        </div>
      </window.Section>
      <window.Section bg={GV.g50} pad="64px 0 0">
        <window.CTABand overline="Turn the score into certification" title="Have a practitioner walk you through your results" body="Your readiness report is a starting point. Our team can validate every gap, tailor the toolkit, and prepare you for a CMMI Lead Appraiser." primary="Talk to a practitioner" onNav={onNav} dest="contact" />
      </window.Section>
    </div>
  );
};

/* ── RESULTS PDF ──────────────────────────────────────────── */
function genEvalPDFCMMI(results, user) {
  const lib=window.jspdf; if(!lib||!lib.jsPDF){alert('PDF engine is still loading.');return;}
  const {themes,overall,gaps,band,totalControls,level}=results;
  const doc=new lib.jsPDF({unit:'pt',format:'a4'}); const W=doc.internal.pageSize.getWidth(); const H=doc.internal.pageSize.getHeight(); const M=50;
  const PURPLE=[91,46,145],ORANGE=[232,98,42],INK=[30,30,46],GREY=[120,120,134]; let y=100;
  doc.setFillColor(...PURPLE);doc.rect(0,0,W,70,'F');doc.setFillColor(...ORANGE);doc.rect(W-M-11,28,11,11,'F');doc.setTextColor(255,255,255);doc.setFont('helvetica','bold');doc.setFontSize(15);doc.text('VERIGO GLOBAL',M,33);doc.setFont('helvetica','normal');doc.setFontSize(8.5);doc.setTextColor(214,204,232);doc.text('Compliance by Design',M,49);doc.setTextColor(255,255,255);doc.setFontSize(8.5);doc.text('CMMI v2.0',W-M-20,35,{align:'right'});
  doc.setTextColor(...INK);doc.setFont('helvetica','bold');doc.setFontSize(21);doc.text('CMMI v2.0 Readiness Report',M,y);y+=12;
  doc.setDrawColor(...ORANGE);doc.setLineWidth(2.5);doc.line(M,y,M+54,y);y+=16;
  doc.setFont('helvetica','normal');doc.setFontSize(10);doc.setTextColor(...GREY);doc.text(String(level||''),M,y);y+=18;
  doc.setFont('helvetica','bold');doc.setFontSize(40);doc.setTextColor(...PURPLE);doc.text(String(overall),M,y+14);doc.setFontSize(11);doc.setTextColor(...GREY);doc.setFont('helvetica','normal');doc.text('/ 100',M+58,y+14);doc.setFont('helvetica','bold');doc.setFontSize(13);doc.setTextColor(...INK);doc.text('Overall maturity: '+band[1],M+130,y-2);doc.setFont('helvetica','normal');doc.setFontSize(10);doc.setTextColor(...GREY);doc.splitTextToSize('~'+gaps+' of '+(totalControls||60)+' practices need attention. '+band[3],W-M-(M+130)).forEach((ln,i)=>doc.text(ln,M+130,y+14+i*13));y+=56;
  if(user&&(user.company||user.name)){doc.setDrawColor(224,224,232);doc.setLineWidth(0.5);doc.line(M,y,W-M,y);y+=16;doc.setFontSize(9);doc.setTextColor(...PURPLE);doc.setFont('helvetica','bold');doc.text('Prepared for '+(user.company||user.name),M,y);doc.setFont('helvetica','normal');doc.setTextColor(...GREY);doc.text(new Date().toLocaleDateString('en-US',{year:'numeric',month:'long',day:'numeric'}),W-M,y,{align:'right'});y+=22;}
  doc.setFont('helvetica','bold');doc.setFontSize(12.5);doc.setTextColor(...PURPLE);doc.text('Maturity by practice area',M,y);y+=6;doc.setDrawColor(...PURPLE);doc.setLineWidth(0.8);doc.line(M,y,W-M,y);y+=20;
  const barX=M+220,barW=W-M-barX;
  themes.forEach(t=>{if(y>H-70){doc.addPage();y=60;}doc.setFont('helvetica','bold');doc.setFontSize(9.5);doc.setTextColor(...INK);doc.splitTextToSize(t.theme,200).forEach((ln,i)=>doc.text(ln,M,y+3+i*10));doc.setFillColor(237,237,245);doc.rect(barX,y-7,barW,10,'F');const col=t.pct<60?ORANGE:PURPLE;doc.setFillColor(...col);doc.rect(barX,y-7,barW*(t.pct/100),10,'F');doc.setFont('helvetica','bold');doc.setFontSize(10);doc.setTextColor(...col);doc.text(t.pct+'%',W-M,y+3,{align:'right'});y+=24;});
  const focus=[...themes].sort((a,b)=>a.pct-b.pct).filter(t=>t.pct<80);
  if(focus.length){if(y>H-90){doc.addPage();y=60;}doc.setFont('helvetica','bold');doc.setFontSize(12.5);doc.setTextColor(...PURPLE);doc.text('Recommended next steps',M,y);y+=6;doc.setDrawColor(...PURPLE);doc.setLineWidth(0.8);doc.line(M,y,W-M,y);y+=18;focus.forEach((t,i)=>{if(y>H-90){doc.addPage();y=60;}doc.setFont('helvetica','bold');doc.setFontSize(10.5);doc.setTextColor(...INK);doc.text((i+1)+'. '+t.theme+' ('+t.pct+'%)',M,y);y+=14;doc.setFont('helvetica','normal');doc.setFontSize(9.5);doc.setTextColor(...GREY);doc.splitTextToSize('Toolkit documents: '+t.docs.join(', '),W-2*M-14).forEach(ln=>{doc.text(ln,M+14,y);y+=12;});y+=8;});}
  const total=doc.internal.getNumberOfPages();for(let i=1;i<=total;i++){doc.setPage(i);doc.setDrawColor(224,224,232);doc.setLineWidth(0.5);doc.line(M,H-38,W-M,H-38);doc.setFont('helvetica','normal');doc.setFontSize(8);doc.setTextColor(150,150,160);doc.text('© 2026 Verigo Global · Readiness self-assessment — indicative, not a formal appraisal',M,H-24);doc.text(i+' / '+total,W-M,H-24,{align:'right'});}
  doc.save('Verigo-CMMI-Readiness-Report.pdf');
}

window.EVAL_CMMI = { QUESTIONS:CMMI_Q, sectionsForML:mSectionsForML, computeResults:mCompute, EvalQuiz:EvalQuizCMMI, EvalResults:EvalResultsCMMI, generateEvalPDF:genEvalPDFCMMI };
Object.assign(window, { EvalQuizCMMI, EvalResultsCMMI });
