import fs from 'node:fs'
import path from 'node:path'
const root=process.cwd();const failures=[]
const read=p=>fs.readFileSync(path.join(root,p),'utf8')
const json=p=>JSON.parse(read(p))
const must=(text,needles,scope)=>needles.forEach(needle=>{if(!text.includes(needle))failures.push(`${scope} missing ${needle}`)})

const recipes=json('contracts/screens/kbx.screen-recipes.json')
if(recipes.recipes.length!==9)failures.push(`screen recipes expected 9, found ${recipes.recipes.length}`)
const expected={T01:'list',T02:'master',T03:'transaction',T04:'fast-entry',T05:'master-detail',T06:'queue',T07:'reconcile',T08:'import',T09:'wms-mobile'}
const scenarioIds=new Set(json('contracts/testing/kbx.test-scenarios.json').scenarios.map(item=>item.id))
for(const [code,type] of Object.entries(expected)){
  const recipe=recipes.recipes.find(item=>item.code===code)
  if(!recipe)continue
  if(recipe.type!==type)failures.push(`${code} recipe type must be ${type}`)
  for(const key of ['templateComponent','defaultCommands','requiredPolicies','recoveryPolicies','securityPolicies','canonicalScenarioIds','scaffoldSurfaces'])if(!recipe[key]||!recipe[key].length&&key!=='defaultCommands')failures.push(`${code} recipe missing ${key}`)
  for(const scenarioId of recipe.canonicalScenarioIds)if(!scenarioIds.has(scenarioId))failures.push(`${code} recipe references unknown scenario ${scenarioId}`)
}

const screenContract=read('packages/kbx-contracts/src/screen.ts')
must(screenContract,['KbxScreenTemplateCode','KbxScreenRecipeDefinition','templateCode: KbxScreenTemplateCode'],'screen recipe/type contract')
const generator=read('scripts/generate-screen-recipe-contracts.mjs')
must(generator,['generated/screen-recipe-manifest.json','screenRecipeCatalog.ts'],'screen recipe generator')
const generated=json('generated/screen-recipe-manifest.json')
if(generated.recipes.length!==9)failures.push('generated screen recipe manifest must contain 9 recipes')

const screenManifest=json('generated/screen-manifest.json')
for(const screen of screenManifest){
  const recipe=recipes.recipes.find(item=>item.code===screen.templateCode)
  if(!recipe)failures.push(`${screen.id} missing/unknown templateCode ${screen.templateCode}`)
  else if(recipe.type!==screen.type)failures.push(`${screen.id} ${screen.templateCode}/${screen.type} mismatch`)
}

const frame=read('packages/kbx-ui/src/components/KbxScreenFrame.vue')
must(frame,['KbxScreenTemplateCode','props.screen.templateCode!==props.templateCode'],'runtime templateCode guard')
const wms=read('packages/kbx-ui/src/wms/KbxWmsMobilePage.vue')
must(wms,["props.screen.templateCode!=='T09'"],'T09 runtime recipe guard')

const scaffolder=read('scripts/create-kbx-screen.mjs')
must(scaffolder,["contracts/screens/kbx.screen-recipes.json",'--write-permission is required','permissionKind===\'write\'',"templateCode: '${recipe.code}'",'canonical scenarios:'],'recipe-driven secure scaffolder')
if(scaffolder.includes("const commandMap ="))failures.push('scaffolder must not keep a second hard-coded commandMap beside recipe contract')

const navigation=read('packages/kbx-contracts/src/navigation.ts')
must(navigation,['KbxHomeAttentionSource','KbxHomeAttentionItem','operationId?: string','notificationId?: string'],'Home attention contract')
const homeNav=read('packages/kbx-ui/src/shell/homeNavigation.ts')
must(homeNav,['buildKbxHomeAttention','operation-failed','notification-urgent','operation-running','allowedIds.has'],'Home attention orchestration')
const home=read('packages/kbx-ui/src/shell/KbxHomePage.vue')
must(home,['buildKbxHomeAttention',"@click=\"emit('attention',item)\""],'Home attention UI')
if(home.includes(':operations="homeOperations"'))failures.push('HomePage must receive operations as props, not reference AppFrame state directly')
must(home,['operations?:KbxOperationRun[]','notifications?:KbxUserNotification[]','kbx-home__attention-list','attention:[item:KbxHomeAttentionItem]'],'Home actionable workbench')
const app=read('apps/web/src/shell/KbxAppFrame.vue')
must(app,['homeOperations=computed','homeNotifications=computed','openHomeAttention','safeWorkspacePath(item.screenId,candidate)','알림에 포함된 허용되지 않은 이동 경로를 차단했습니다.',':operations="homeOperations"',':notifications="homeNotifications"','@attention="openHomeAttention"'],'Home runtime security orchestration')

if(failures.length){console.error(failures.join('\n'));process.exit(1)}
console.log(`v35 recipe/navigation validation passed: recipes=${recipes.recipes.length}, screens=${screenManifest.length}; explicit templateCode, canonical scenario closure, secure write scaffolding, and actionable Home attention routing are enforced.`)
