const CATEGORY_API='./api/index.php';
const categoryCtx={csrf:'',user:null,data:null};
const categoryEsc=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
const categoryActive=r=>Number(r?.active)!==0;
const categoryPage=()=>document.querySelector('.breadcrumb strong')?.textContent.trim()||'';
async function categoryApi(action,data){const r=await fetch(`${CATEGORY_API}?action=${action}`,{method:data?'POST':'GET',credentials:'same-origin',headers:data?{'Content-Type':'application/json','X-CSRF-Token':categoryCtx.csrf}:undefined,body:data?JSON.stringify(data):undefined});const j=await r.json().catch(()=>({error:'Server returned an invalid response.'}));if(j.csrf)categoryCtx.csrf=j.csrf;if(!r.ok)throw Error(j.error||'Request failed');return j;}
async function categoryLoad(){const s=await categoryApi('session');categoryCtx.user=s.user;if(!categoryCtx.user||categoryCtx.user.role!=='admin')return false;categoryCtx.data=(await categoryApi('data')).data;return true;}
function categoryRows(){return categoryCtx.data?.categories||[];}
function fillCategorySelects(){const active=categoryRows().filter(categoryActive);const signature=active.map(c=>`${c.id}:${c.name}`).join('|');document.querySelectorAll('.modal .field select[name="category"]').forEach(select=>{if(select.dataset.categorySignature===signature)return;const current=select.value;select.innerHTML=''+active.map(c=>``).join('');if(active.some(c=>c.name===current))select.value=current;select.dataset.categorySignature=signature;});}
function categoryButton(){if(!categoryCtx.user||categoryCtx.user.role!=='admin'||!['Assets','Purchases'].includes(categoryPage()))return;const host=document.querySelector('.page-heading > .heading-actions');if(!host||host.querySelector('[data-category-button]'))return;const button=document.createElement('button');button.type='button';button.className='secondary category-manage-button';button.dataset.categoryButton='1';button.textContent='Manage categories';button.onclick=openCategoryManager;host.append(button);}
function categoryModalMarkup(){return `
ASSETDESK SETTINGS
Manage categories
Active categories appear in asset and purchase forms. Deactivate a category when it has old records; linked categories cannot be permanently deleted.
`;}
function renderCategoryRows(root){const list=root.querySelector('[data-category-list]');const rows=categoryRows();list.innerHTML=rows.length?rows.map(r=>`