import fs from 'node:fs'
const read=p=>fs.readFileSync(p,'utf8')
const failures=[]
const check=(ok,msg)=>{if(!ok)failures.push(msg)}

const feedback=read('packages/kbx-ui/src/components/KbxProblemFeedback.vue')
for(const token of ["'business-rule': '업무 규칙'","permission: '권한'","integration: '외부 연계'","system: '시스템'","allowedActionIds","allowed.value.has(action.id)","retryable","correlationId","role=\"alert\""])
  check(feedback.includes(token),`KbxProblemFeedback missing: ${token}`)
check(!feedback.includes('v-html'),'Problem feedback must not render server problem text as raw HTML')

for(const [file,name] of [
  ['packages/kbx-ui/src/components/KbxListPage.vue','T01'],
  ['packages/kbx-ui/src/components/KbxMasterPage.vue','T02'],
  ['packages/kbx-ui/src/components/KbxTransactionPage.vue','T03'],
]){
  const source=read(file)
  for(const token of ['KbxProblemFeedback','problem?:','problemActionAllowlist','retryProblem','dismissProblem']) check(source.includes(token),`${name} template problem contract missing: ${token}`)
}

const listVm=read('apps/web/src/modules/oms/orders/search/useOrderSearch.ts')
for(const token of ['type KbxProblem','const problem = ref<KbxProblem | null>(null)',"failedCommand = ref<'ship' | null>","if(isKbxProblem(error))","failedCommand.value='ship'","async function retryProblem","function dismissProblem"])
  check(listVm.includes(token),`OMS-ORD-001 problem recovery missing: ${token}`)
const listPage=read('apps/web/src/modules/oms/orders/search/OrderListPage.vue')
check(listPage.includes(':problem="vm.problem.value"')&&listPage.includes('@retry-problem="vm.retryProblem"')&&listPage.includes('@dismiss-problem="vm.dismissProblem"'),'OMS-ORD-001 must bind actionable command problem feedback')
check(!listPage.includes('@problem-action="executeCommand"'),'Server-provided problem action ids must not be wired directly to arbitrary screen commands')

const txVm=read('apps/web/src/modules/oms/orders/register/useOrderRegistration.ts')
for(const token of ['const problem=ref<KbxProblem|null>(null)',"failedAction=ref<'save'|'confirm'|null>","problem.value=issue","failedAction.value='save'","failedAction.value='confirm'","async function retryProblem","function dismissProblem"])
  check(txVm.includes(token),`OMS-ORD-002 problem recovery missing: ${token}`)
const txPage=read('apps/web/src/modules/oms/orders/register/OrderRegisterPage.vue')
check(txPage.includes(':problem="vm.problem.value"')&&txPage.includes('@retry-problem="vm.retryProblem"')&&txPage.includes('@dismiss-problem="vm.dismissProblem"'),'OMS-ORD-002 must bind actionable command problem feedback')

const master=read('apps/web/src/modules/erp/items/ItemMasterPage.vue')
for(const token of ['const problem = ref<KbxProblem | null>(null)',"failedCommand = ref<'load'|'save'|'deactivate'|null>","failedCommand.value = 'load'","failedCommand.value = 'save'","failedCommand.value = 'deactivate'","async function retryProblem","function dismissProblem",':problem="problem"'])
  check(master.includes(token),`ERP-MST-ITEM-001 problem recovery missing: ${token}`)

const ref=read('apps/web/fe-reference/kbx-fe.js')
for(const token of ['commandProblem:null','function problemSurface(problem)','data-problem-type','show-blocked','출고할 수 없는 주문이 포함되어 있습니다.'])
  check(ref.includes(token),`FE Reference actionable problem parity missing: ${token}`)
const css=read('apps/web/fe-reference/kbx-fe.css')
for(const token of ['.problem-feedback{','.problem-feedback.warning','.problem-feedback.danger','.problem-actions'])
  check(css.includes(token),`FE Reference problem theme CSS missing: ${token}`)

if(failures.length){console.error('FE problem/recovery v47 validation failed:');for(const f of failures)console.error(`- ${f}`);process.exit(1)}
console.log('FE problem/recovery v47 PASS: T01/T02/T03 command problems, retry/dismiss, action allow-list security, themed HTML/JS parity.')
