import fs from 'node:fs';
import path from 'node:path';
import {frame,C,rect,text,label,line} from './design-lib.mjs';
export function destination(r){
if(r==='/')return 'sign-in';
if(r.includes('mfa'))return r.includes('complete')?'overview':'mfa-challenge';
if(r.includes('setup'))return r.includes('/ai/')?'ai-context':'onboarding';
if(r==='/404')return 'state-not-found';if(r==='/500')return 'state-partial-failure';if(r==='/offline')return 'state-offline';if(r.includes('unverified'))return 'authentication';if(r==='/ui-harness')return 'components-controls';if(r.includes('/teams/'))return 'integrations';
if(r.includes('/profile/'))return ({general:'profile',appearance:'profile',authentication:'authentication',notifications:'integrations',api:'tokens',add:'token-create'})[r.split('/').pop()]||'profile';
if(r.includes('/applications')){if(r.endsWith('/create'))return 'app-create';if(r.includes('demo-environment'))return 'preview-config';if(r.includes('/demos/'))return 'preview-detail';if(r.endsWith('/deploy'))return 'app-deploy';if(r.endsWith('/settings'))return 'app-settings';return r.includes('[applicationId]')?'app-overview':'applications';}
if(r.includes('/stack-profiles')){if(r.includes('/demos/'))return 'preview-detail';if(r.endsWith('/edit')||r.endsWith('/create'))return 'stack-builder';return r.includes('[profileId]')?'profile-detail':'stack-profiles';}
if(r.includes('/clusters/cluster/imported/')){
if(r.includes('/kubernetes/')){const part=r.split('/kubernetes/')[1];if(part.includes('['))return part.startsWith('workloads/pods')?'pod-detail':part.startsWith('nodes')?'node-detail':'resource-detail';if(part.includes('workloads'))return 'workloads';if(part==='logs')return 'logs';if(part==='events')return 'events';if(part==='nodes')return 'nodes';if(part.startsWith('storage/'))return 'storage';if(part.startsWith('networking/'))return 'networking';if(part==='helm/releases')return 'catalog-detail';return 'configuration';}
if(r.includes('/settings/')){const last=r.split('/').pop();return ({'ai-context-repos':'ai-context',credentials:'credential-detail',variables:'variables',audit:'audit-log',access:'roles',nodes:'nodes'})[last]||'cluster-settings';}
if(r.includes('/decommission-argocd'))return 'operation-detail';if(r.includes('/ai-insights'))return r.includes('[insightId]')?'condition-detail':'conditions';
if(r.includes('/add-ons'))return r.includes('resource-map')?'stack-builder':r.includes('[addonName]')?'catalog-detail':'stacks';
if(r.includes('/stacks'))return r.endsWith('/edit')||r.endsWith('/create')?'stack-builder':r.includes('[stackName]')?'stack-review':'stacks';
if(r.includes('/operations'))return r.includes('[operationId]')?'operation-detail':'operations';
if(r.includes('/resources'))return r.includes('[resourceId]')?'resource-detail':'resources';
if(r.includes('/nodes'))return r.endsWith('groups')?'node-groups':'nodes';
return ({overview:'cluster-overview',mesh:'mesh',metrics:'metrics',security:'security',manifests:'configuration',troubleshooting:'ai-investigation'})[r.split('/').pop()]||'cluster-overview';}
if(r.startsWith('/organisation/clusters')){if(r.endsWith('/create'))return 'cluster-create';if(r.includes('/create-'))return r.endsWith('playground')?'onboarding':'cluster-configure';if(r.includes('/import'))return 'cluster-import';return 'clusters';}
if(r.includes('/cluster-meshes'))return 'mesh';
if(r.includes('/ai/')){if(r.includes('/settings/')){if(r.includes('/connections'))return 'integrations';return ({models:'ai-models',capabilities:'ai-capabilities',autonomy:'ai-autonomy',workspaces:'ai-context',memory:'ai-context',feedback:'ai-usage'})[r.split('/').pop()]||'ai-models';}if(r.includes('/agents/runs/'))return 'agent-run-detail';if(r.endsWith('/agents/runs'))return 'agent-runs';if(r.includes('/agents/'))return 'agent-detail';if(r.endsWith('/agents'))return 'agents';if(r.includes('/alerts'))return /create|update/.test(r)?'alert-create':r.includes('[alertId]')?'alert-detail':'alerts';if(r.includes('/board/'))return 'task-detail';if(r.endsWith('/board'))return 'ai-board';if(r.includes('/conditions/'))return 'condition-detail';if(r.endsWith('/conditions'))return 'conditions';return ({chat:'ai-chat',inbox:'inbox',automations:'automations',settings:'ai-models',usage:'ai-usage'})[r.split('/').pop()]||'ai-home';}if(r.endsWith('/ai'))return 'ai-home';
if(r.includes('/security')){if(r.includes('/advisories/'))return 'security-finding';return ({security:'security',clusters:'security-workloads',workloads:'security-workloads',findings:'security-findings',sbom:'security-sbom',policies:'security-policies','network-exposure':'security-network',compliance:'compliance',print:'compliance-report'})[r.split('/').pop()]||'security';}
if(r.includes('/cost')){if(r.endsWith('compare'))return 'cost-compare';if(r.includes('/clusters'))return 'cost-clusters';if(r.includes('/credentials'))return 'cost-providers';return ({cost:'cost',savings:'cost-savings',settings:'cost-settings',workloads:'cost-workloads'})[r.split('/').pop()]||'cost';}
if(r.includes('/charts')){if(r.includes('/repositories/'))return 'registry-detail';if(r.endsWith('repositories'))return 'registries';return r==='/organisation/charts'?'catalog':'catalog-detail';}if(r.includes('/add-ons'))return r==='/organisation/add-ons'?'catalog':'catalog-detail';
if(r.includes('/credentials'))return r.endsWith('/add')?'credential-add':r==='/organisation/credentials'?'credentials':'credential-detail';
if(r.includes('/billing'))return r.endsWith('invoices')?'invoices':r.endsWith('plan')?'billing-plan':'billing';
if(r.includes('/settings/'))return ({general:'org-settings',backups:'backups',cloudflare:'dns',dns:'dns',encryption:'encryption',pipelines:'pipelines',variables:'variables',slack:'integrations',integrations:'integrations',skills:'ai-context',ai:'ai-autonomy','ai-provider':'ai-models'})[r.split('/').pop()]||'org-settings';
if(r.includes('/support'))return r.endsWith('create')?'support-create':r.endsWith('[ticketId]')||r.endsWith('submitted')?'support-detail':'support';
if(r.includes('/operations/'))return 'operation-detail';if(r.endsWith('/activity/snoozes'))return 'activity-snoozes';if(r.endsWith('/activity'))return 'inbox';
return ({dashboard:'overview',members:'members',roles:'roles','audit-log':'audit-log','service-tokens':'tokens',add:'member-invite',invites:'members',create:'onboarding',switch:'org-settings'})[r.split('/').pop()]||'org-settings';
}
export function createCoverage(root,boards){const inv=fs.existsSync(path.join(root,'audit/source-inventory.json'))?JSON.parse(fs.readFileSync(path.join(root,'audit/source-inventory.json'),'utf8')):null;const ssr=inv?[1,2,3].flatMap(i=>JSON.parse(fs.readFileSync(path.join(root,`audit/live-structure-${i}.json`),'utf8'))):[];const coverage=inv?inv.pages.map(p=>{const id=destination(p.route);const b=boards.find(b=>b.id===id);if(!b)throw new Error('Missing destination '+id+' for '+p.route);const sr=ssr.find(x=>x.route===p.route);return {route:p.route,live:p.live,localSource:!!p.source,reviewMethod:[p.source?'Source module + imported implementation inventory':null,sr?'Live server-rendered structure (hydrated state not implied)':null].filter(Boolean).join('; ')||'Live route manifest; shared pattern review',screenId:id,screenTitle:b.title,chapter:b.chapter,pattern:p.route.includes('[')?'Parameterized page / shared pattern':'Page or redirect',serverStatus:sr?.status||null};}):JSON.parse(fs.readFileSync(path.join(root,'audit/route-coverage.json'),'utf8')).map(r=>{const id=destination(r.route),b=boards.find(b=>b.id===id);if(!b)throw new Error('Missing destination '+id);return {...r,screenId:id,screenTitle:b.title,chapter:b.chapter};});fs.writeFileSync(path.join(root,'audit/route-coverage.json'),JSON.stringify(coverage,null,2));const quote=v=>'"'+String(v??'').replaceAll('"','""')+'"';const keys=Object.keys(coverage[0]);fs.writeFileSync(path.join(root,'route-coverage.csv'),[keys.map(quote).join(','),...coverage.map(x=>keys.map(k=>quote(x[k])).join(','))].join('\n')+'\n');
const chunks=[];for(let i=0;i<coverage.length;i+=16)chunks.push(coverage.slice(i,i+16));chunks.forEach((rows,i)=>frame('coverage-'+(i+1),'Route coverage / '+String(i+1).padStart(2,'0'),'10 / Route coverage',()=>{rect(0,0,1440,1000,C.paper);label(45,38,'Ankra / Current routes → redesigned destinations');text(45,78,'No workflow left without a home.',33,C.ink,600,1342);text(45,139,'252 live routes · 253 in combined inventory · every route maps to a designed page or shared pattern.',13,C.muted,400,1342);rect(44,187,1352,35,C.soft,4);text(58,196,'EXISTING PAGE / ROUTE PATTERN',10,C.muted,600,715);text(843,196,'REDESIGNED DESTINATION',10,C.muted,600,433);rows.forEach((r,j)=>{const y=240+j*42;const short=r.route.replace('/organisation/clusters/cluster/imported/[clusterId]','/cluster/:id').replace('/organisation/[organisationId]','/org/:id').replace('/organisation','/org').replaceAll('[namespace]',':namespace').replaceAll('[name]',':name');text(58,y,short,10,C.ink,400,751);text(843,y,r.screenTitle,11,C.green,500,529,{target:r.screenId});line(45,y+34,1350);});text(45,949,'Full paths, source coverage, and review method: route-coverage.csv',12,C.muted,400,1250);},{kind:'coverage'}));return coverage;}
