(() => {
  'use strict';

  const html = document.documentElement;
  const theme = html.dataset.scrollTheme || '';
  const mobile = matchMedia('(max-width:54rem)');

  const projectPath = path => `/projects/${path}/`;
  const configs = {
    'computer-vision': {
      mark:'CV', title:'Pusat Penelitian CV', subtitle:'Klasifikasi Gambar',
      items:[
        ['▦','Gambaran Ikhtisar',projectPath('computer-vision')],
        ['◫','Dataset',projectPath('computer-vision/dataset')],
        ['△','Model',projectPath('computer-vision/model')],
        ['⌁','Hasil',projectPath('computer-vision/results')],
        ['⚠','Analisis Kegagalan',projectPath('computer-vision/analysis')],
        ['✓','Keterbatasan',projectPath('computer-vision/limitations')],
        ['</>','Kode Sumber',projectPath('computer-vision/code')],
        ['▤','Laporan Teknis',projectPath('computer-vision/report')]
      ]
    },
    'sentiment-analysis': {
      mark:'NLP', title:'Analisis Sentimen Teks', subtitle:'SentiScope Dashboard',
      items:[
        ['▦','Gambaran Ikhtisar',projectPath('sentiment-analysis')],
        ['☷','Penjelajah Umpan Balik',projectPath('sentiment-analysis/feedback')],
        ['＋','Kirim Umpan Balik',projectPath('sentiment-analysis/feedback/new')],
        ['◫','Analisis Topik',projectPath('sentiment-analysis/topics')],
        ['⌕','Kata Kunci',projectPath('sentiment-analysis/keywords')],
        ['▥','Kategori',projectPath('sentiment-analysis/categories')],
        ['✦','Rekomendasi',projectPath('sentiment-analysis/recommendations')],
        ['△','Evaluasi Model',projectPath('sentiment-analysis/model')]
      ]
    }
  };

  function normalizedPath(){
    let p = location.pathname.replace(/\/index\.html$/,'/');
    if (!p.endsWith('/')) p += '/';
    return p;
  }

  function closeProject(event){
    event?.preventDefault?.();
    try{
      if (window.parent && window.parent !== window){
        window.parent.postMessage({type:'apu:close-project',project:theme},location.origin);
        return;
      }
    }catch(_){ }
    location.href='/';
  }

  function removeLegacyForNative(){
    if (!configs[theme]) return;
    document.querySelectorAll([
      '.apu-final-mobile-bar:not(.apu-v69-malaysia-nav)', '.apu-final-mobile-drawer', '.apu-final-mobile-scrim',
      '.apu-v52-cv-bar','.apu-v52-cv-scrim','.apu-v54-cv-mobile-bar','.apu-v54-cv-mobile-drawer','.apu-v54-cv-mobile-scrim',
      '.apu-v5-mobile-project-bar','.apu-v5-mobile-nav-drawer','.apu-mobile-header-v65','.apu-mobile-drawer-v65','.apu-mobile-scrim-v65'
    ].join(',')).forEach(node => node.remove());
  }

  function installNativeNav(){
    const config = configs[theme];
    if (!config || !mobile.matches) return;
    removeLegacyForNative();
    if (document.querySelector('.apu-v69-malaysia-nav')) return;

    html.dataset.apuV69NativeNav='true';
    const path = normalizedPath();
    const current = config.items.find(item => item[2] === path) || config.items[0];
    const bar = document.createElement('header');
    bar.className='apu-final-mobile-bar apu-v69-malaysia-nav';
    bar.innerHTML=`
      <span class="apu-v69-native-mark" aria-hidden="true">${config.mark}</span>
      <div class="apu-v69-native-brand"><strong>${config.title}</strong><small>${current[1]}</small></div>
      <button class="apu-v69-native-toggle" type="button" aria-expanded="false" aria-controls="apuV69NativeMenu" aria-label="Buka menu navigasi">☰</button>`;

    const menu = document.createElement('nav');
    menu.className='apu-v69-malaysia-menu';
    menu.id='apuV69NativeMenu';
    menu.setAttribute('aria-label',`${config.title} navigation`);
    menu.innerHTML=config.items.map(([icon,label,href]) =>
      `<a href="${href}"${href===path?' aria-current="page"':''}><span aria-hidden="true">${icon}</span><span>${label}</span></a>`
    ).join('');

    const anchor=document.querySelector('#root,#app,.sp-app') || document.body.firstElementChild;
    document.body.insertBefore(bar,anchor||null);
    document.body.insertBefore(menu,anchor||null);
    const toggle=bar.querySelector('.apu-v69-native-toggle');
    const setOpen=open=>{
      html.dataset.apuV69MenuOpen=String(open);
      menu.classList.toggle('is-open',open);
      toggle.setAttribute('aria-expanded',String(open));
      toggle.textContent=open?'×':'☰';
      toggle.setAttribute('aria-label',open?'Tutup menu navigasi':'Buka menu navigasi');
    };
    toggle.addEventListener('click',()=>setOpen(!menu.classList.contains('is-open')));
    menu.addEventListener('click',event=>{
      const exit=event.target.closest('.apu-v69-exit-link');
      if(exit){closeProject(event);return;}
      if(event.target.closest('a[href]')) setOpen(false);
    });
    document.addEventListener('keydown',event=>{if(event.key==='Escape')setOpen(false)});
  }

  function compactComputerVision(){
    if(theme!=='computer-vision'||!mobile.matches)return;
    const run=()=>{
      const root=document.getElementById('root');
      if(!root)return;
      // Hide the React sidebar and original mobile header, but retain the route content.
      [...root.querySelectorAll('aside')].forEach(node=>node.style.setProperty('display','none','important'));
      [...root.querySelectorAll('header')].filter(node=>node.querySelector('button')&&!node.querySelector('h1')).forEach(node=>node.style.setProperty('display','none','important'));
      const h1=[...root.querySelectorAll('h1')].find(node=>/computer vision|image classification|klasifikasi gambar|visi komputer/i.test(node.textContent||''));
      if(!h1)return;
      let node=h1.parentElement;
      let depth=0;
      while(node&&node!==root&&depth++<7){
        node.classList.add('apu-v69-cv-compact');
        node.style.setProperty('min-height','0','important');
        node.style.setProperty('height','auto','important');
        node.style.setProperty('max-height','none','important');
        node.style.setProperty('justify-content','flex-start','important');
        node.style.setProperty('align-items','stretch','important');
        node=node.parentElement;
      }
      // Remove any purely decorative empty block before the heading when it consumes a large viewport area.
      const main=h1.closest('main');
      if(main){
        const all=[...main.querySelectorAll('*')];
        all.forEach(el=>{
          if(el.contains(h1)||h1.contains(el))return;
          const text=(el.textContent||'').replace(/\s+/g,'').trim();
          const r=el.getBoundingClientRect();
          const cs=getComputedStyle(el);
          const decorative=!text&&!el.querySelector('img,video,canvas,svg,input,button,a');
          if(decorative&&r.height>220&&(cs.position==='static'||cs.position==='relative'))el.classList.add('apu-v69-cv-empty-spacer');
        });
        main.scrollTop=0;
      }
    };
    run();setTimeout(run,350);setTimeout(run,1100);setTimeout(run,2600);
  }

  function installSolidLanguageMenu(){
    const select=document.getElementById('viewerLanguageControl');
    const label=select?.closest('.viewer__language-control');
    const controls=document.getElementById('viewerDisplayControls');
    if(!select||!label||!controls||document.querySelector('.apu-v69-language-button'))return;
    const button=document.createElement('button');
    button.type='button';button.className='apu-v69-language-button';button.textContent='文';
    button.setAttribute('aria-label','Pilih bahasa terjemahan');button.setAttribute('aria-expanded','false');
    controls.insertBefore(button,label.nextSibling);
    const menu=document.createElement('div');menu.className='apu-v69-language-menu';menu.setAttribute('role','menu');
    [...select.options].forEach(option=>{
      const item=document.createElement('button');item.type='button';item.setAttribute('role','menuitem');item.dataset.value=option.value;item.textContent=option.textContent;
      item.setAttribute('aria-current',String(select.value===option.value));
      item.addEventListener('click',()=>{
        select.value=option.value;
        select.dispatchEvent(new Event('input',{bubbles:true}));
        select.dispatchEvent(new Event('change',{bubbles:true}));
        [...menu.querySelectorAll('button')].forEach(b=>b.setAttribute('aria-current',String(b===item)));
        closeMenu();
      });
      menu.appendChild(item);
    });
    document.body.appendChild(menu);
    const place=()=>{
      const r=button.getBoundingClientRect();
      const width=Math.min(250,innerWidth-20);
      let left=Math.max(10,Math.min(innerWidth-width-10,r.left));
      let top=r.bottom+8;
      if(top+Math.min(420,innerHeight-24)>innerHeight-8)top=Math.max(8,r.top-Math.min(420,innerHeight-24)-8);
      menu.style.left=`${left}px`;menu.style.top=`${top}px`;
    };
    const closeMenu=()=>{menu.classList.remove('is-open');button.setAttribute('aria-expanded','false')};
    button.addEventListener('click',event=>{event.stopPropagation();const open=!menu.classList.contains('is-open');if(open){place();menu.classList.add('is-open')}else closeMenu();button.setAttribute('aria-expanded',String(open))});
    addEventListener('resize',()=>{if(menu.classList.contains('is-open'))place()},{passive:true});
    document.addEventListener('click',event=>{if(!menu.contains(event.target)&&event.target!==button)closeMenu()});
    document.addEventListener('keydown',event=>{if(event.key==='Escape')closeMenu()});
  }

  const records=[
    ['The new lab computers are fast and reliable.','Positive','Positive','94%','Clear positive'],
    ['The lecturer explains difficult topics very clearly.','Positive','Positive','92%','Clear positive'],
    ['Campus Wi-Fi is much more stable this semester.','Positive','Positive','89%','Clear positive'],
    ['The library is quiet and comfortable for studying.','Positive','Positive','87%','Clear positive'],
    ['The cafeteria is good, but queues are still too long.','Positive','Neutral','68%','Mixed sentiment'],
    ['The registration portal failed before the deadline.','Negative','Negative','93%','Clear negative'],
    ['The classroom projector often disconnects.','Negative','Negative','88%','Clear negative'],
    ['Support responses take too long during peak hours.','Negative','Negative','84%','Clear negative'],
    ['Great, another outage exactly when I need the portal.','Negative','Positive','61%','Sarcasm'],
    ['The tutorial was not bad, but needs advanced examples.','Neutral','Negative','64%','Negation'],
    ['The course schedule was updated yesterday.','Neutral','Neutral','82%','Factual neutral'],
    ['The room is adequate and the facilities are average.','Neutral','Neutral','79%','Balanced neutral']
  ];

  function modelMarkup(){
    const rows=records.map((r,i)=>`<tr><td>${String(i+1).padStart(2,'0')}</td><td>${r[0]}</td><td>${r[1]}</td><td class="${r[1]===r[2]?'apu-v69-good':'apu-v69-bad'}">${r[2]}</td><td>${r[3]}</td><td>${r[4]}</td></tr>`).join('');
    return `<main class="apu-v69-model-evaluation" id="apuV69ModelEvaluation" translate="yes"><div class="apu-v69-model-inner">
      <p class="apu-v69-model-eyebrow">NLP · Evaluasi Model · Data Demonstrasi Lokal</p>
      <h1>Evaluasi Model Sentimen</h1>
      <p class="apu-v69-model-lead">Evaluasi lengkap terhadap 12 umpan balik mahasiswa berlabel. Data, confusion matrix, laporan per kelas, dan analisis kesalahan tersedia langsung di browser tanpa API eksternal.</p>
      <section class="apu-v69-metrics" aria-label="Metrik model">
        <article class="apu-v69-metric"><small>Akurasi</small><strong>75.0%</strong></article>
        <article class="apu-v69-metric"><small>Precision Makro</small><strong>73.9%</strong></article>
        <article class="apu-v69-metric"><small>Recall Makro</small><strong>73.9%</strong></article>
        <article class="apu-v69-metric"><small>F1 Makro</small><strong>73.9%</strong></article>
      </section>
      <section class="apu-v69-model-grid">
        <article class="apu-v69-panel"><h2>Confusion Matrix</h2><div class="apu-v69-table-wrap"><table class="apu-v69-matrix"><thead><tr><th>Aktual ↓</th><th>Positif</th><th>Negatif</th><th>Netral</th></tr></thead><tbody><tr><th>Positif</th><td class="is-correct">4</td><td>0</td><td>1</td></tr><tr><th>Negatif</th><td>1</td><td class="is-correct">3</td><td>0</td></tr><tr><th>Netral</th><td>0</td><td>1</td><td class="is-correct">2</td></tr></tbody></table></div></article>
        <article class="apu-v69-panel"><h2>Laporan Per Kelas</h2><div class="apu-v69-table-wrap"><table class="apu-v69-table"><thead><tr><th>Kelas</th><th>Precision</th><th>Recall</th><th>F1</th><th>Support</th></tr></thead><tbody><tr><td>Positif</td><td>80.0%</td><td>80.0%</td><td class="apu-v69-good">80.0%</td><td>5</td></tr><tr><td>Negatif</td><td>75.0%</td><td>75.0%</td><td class="apu-v69-warn">75.0%</td><td>4</td></tr><tr><td>Netral</td><td>66.7%</td><td>66.7%</td><td class="apu-v69-bad">66.7%</td><td>3</td></tr></tbody></table></div></article>
      </section>
      <section class="apu-v69-panel" style="margin-top:16px"><h2>Dataset Evaluasi — 12 Rekaman</h2><div class="apu-v69-table-wrap"><table class="apu-v69-table"><thead><tr><th>#</th><th>Teks Umpan Balik</th><th>Label Aktual</th><th>Prediksi</th><th>Keyakinan</th><th>Catatan</th></tr></thead><tbody>${rows}</tbody></table></div></section>
      <section class="apu-v69-model-grid">
        <article class="apu-v69-panel"><h2>Analisis Kesalahan</h2><div class="apu-v69-error-list"><div class="apu-v69-error"><p>“The cafeteria is good, but queues are still too long.”</p><div class="apu-v69-tags"><span class="apu-v69-tag">Aktual: positif</span><span class="apu-v69-tag">Prediksi: netral</span><span class="apu-v69-tag">Mixed sentiment</span></div></div><div class="apu-v69-error"><p>“Great, another outage exactly when I need the portal.”</p><div class="apu-v69-tags"><span class="apu-v69-tag">Aktual: negatif</span><span class="apu-v69-tag">Prediksi: positif</span><span class="apu-v69-tag">Sarcasm</span></div></div><div class="apu-v69-error"><p>“The tutorial was not bad, but needs advanced examples.”</p><div class="apu-v69-tags"><span class="apu-v69-tag">Aktual: netral</span><span class="apu-v69-tag">Prediksi: negatif</span><span class="apu-v69-tag">Negation</span></div></div></div></article>
        <article class="apu-v69-panel"><h2>Kesimpulan Teknis</h2><div class="apu-v69-error-list"><div class="apu-v69-error"><p><strong>Kekuatan:</strong> model stabil pada teks positif dan negatif yang eksplisit.</p></div><div class="apu-v69-error"><p><strong>Kelemahan:</strong> ironi, negasi, dan sentimen campuran menurunkan performa kelas netral.</p></div><div class="apu-v69-error"><p><strong>Perbaikan berikutnya:</strong> tambah data berbahasa Indonesia, fitur negasi, embedding kontekstual, dan validasi silang berstratifikasi.</p></div></div></article>
      </section>
      <p class="apu-v69-model-note">Semua angka berasal dari confusion matrix yang ditampilkan: 9 prediksi benar dari 12 rekaman menghasilkan akurasi 75.0%. Halaman ini tidak akan bergantung pada respons API sehingga tidak berubah menjadi layar putih.</p>
    </div></main>`;
  }

  function mountModelEvaluation(){
    if(theme!=='sentiment-analysis'||!(html.dataset.apuModelEvaluation==='true'||/\/model\/?(?:index\.html)?$/.test(location.pathname)))return;
    const nav=document.querySelector('.apu-v69-malaysia-menu');
    let model=document.getElementById('apuV69ModelEvaluation');
    if(!model){
      const holder=document.createElement('div');holder.innerHTML=modelMarkup();model=holder.firstElementChild;
      const root=document.getElementById('root');
      if(root){root.style.setProperty('display','none','important');root.insertAdjacentElement('beforebegin',model)}
      else document.body.appendChild(model);
    }
    const root=document.getElementById('root');if(root)root.style.setProperty('display','none','important');
    if(nav&&model.compareDocumentPosition(nav)&Node.DOCUMENT_POSITION_FOLLOWING){} // keep nav order unchanged
  }

  function enhanceAiArchitect(){
    if(theme!=='ai-architect'||!matchMedia('(max-width:767px)').matches)return;
    const run=()=>{
      const drawer=document.querySelector('aside.ai-architect-drawer')||[...document.querySelectorAll('aside')].find(n=>/Enterprise RAG/.test(n.textContent||'')&&/Cloud Compare/.test(n.textContent||''));
      const trigger=document.querySelector('header .ai-menu-trigger')||document.querySelector('header button.md\\:hidden')||[...document.querySelectorAll('header button')].find(n=>n.querySelector('svg'));
      if(drawer){drawer.classList.add('ai-architect-drawer');const nav=drawer.querySelector('nav')||drawer;let contact=[...nav.querySelectorAll('a')].find(a=>/contact|kontak/i.test(a.textContent||'')||/\/contact/.test(a.getAttribute('href')||''));if(!contact){contact=document.createElement('a');contact.href='/projects/ai-architect/contact/';contact.innerHTML='<span>✉</span><span>Kontak & Book a Call</span>';nav.appendChild(contact)}contact.classList.add('apu-v69-contact-link');}
      if(trigger){trigger.classList.add('ai-menu-trigger');trigger.closest('header')?.classList.add('ai-architect-header');trigger.setAttribute('aria-label','Buka navigasi AI Architect Lab')}
    };
    run();setTimeout(run,500);setTimeout(run,1600);
  }

  function removeAcademIqCross(){
    if(theme!=='student-performance')return;
    document.querySelectorAll('.apu-final-mobile-exit').forEach(node=>node.remove());
  }

  function maintain(){
    installSolidLanguageMenu();
    if(configs[theme]&&mobile.matches){installNativeNav();removeLegacyForNative();compactComputerVision();}
    enhanceAiArchitect();removeAcademIqCross();mountModelEvaluation();
  }

  function boot(){
    maintain();
    let cycles=0;
    const observer=new MutationObserver(()=>{maintain();if(++cycles>240)observer.disconnect()});
    observer.observe(document.documentElement,{childList:true,subtree:true});
    setTimeout(()=>observer.disconnect(),20000);
  }
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot,{once:true});else boot();
  addEventListener('load',maintain,{once:true});
})();
