#!/usr/bin/env bun
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
import { join } from 'path'

const root = process.cwd()
const outRoot = join(root, 'content_population_exports')
mkdirSync(outRoot, { recursive: true })
const generatedAt = new Date().toISOString()

function readJson(path: string, fallback: any = null) {
  if (!existsSync(path)) return fallback
  return JSON.parse(readFileSync(path, 'utf8').replace(/^\uFEFF/, ''))
}
function csv(rows: any[], headers: string[]) {
  const esc = (value: any) => {
    if (Array.isArray(value)) value = value.join(' | ')
    if (value === undefined || value === null) value = ''
    value = String(value)
    return /[",\n\r]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value
  }
  return [headers.join(','), ...rows.map(row => headers.map(header => esc(row[header])).join(','))].join('\n') + '\n'
}

const handoff = readJson(join(outRoot, 'handoff_manifest.json'), {})
const readiness = readJson(join(outRoot, 'content_population_readiness.json'), {})
const blank = readJson(join(outRoot, 'clinical_blank_decision_template.json'), {})
const approvals = readJson(join(outRoot, 'product_approval_decision_gate.json'), {})
const staging = readJson(join(outRoot, 'staging_evidence_validation.json'), {})
const verifier = readJson(join(outRoot, 'handoff_verification_run.json'), {})

const lanes = [
  {
    Lane: 'Compliance clinical claim decisions',
    Owner: 'Compliance owner / Umar',
    StartCount: blank.counts?.decisions ?? 185,
    DoneCount: blank.counts?.validBlankApprovals ?? 0,
    RemainingCount: (blank.counts?.decisions ?? 185) - (blank.counts?.validBlankApprovals ?? 0),
    EvidenceFile: 'data/content/compliance/clinical-blank-decisions.json',
    Command: 'bun run compliance:blank-decisions && bun run claims:sync-content && bun run export:content',
    ClearsBlockerType: 'compliance',
    CurrentBlockers: handoff.blockerSummary?.compliance ?? 0,
    StopRule: 'Use source-backed claim refs or explicit approved_blank rows only; no generated clinical claims.'
  },
  {
    Lane: 'Product approval decisions',
    Owner: 'Umar / JV reviewer',
    StartCount: approvals.counts?.products ?? 190,
    DoneCount: approvals.counts?.validApprovals ?? 0,
    RemainingCount: (approvals.counts?.products ?? 190) - (approvals.counts?.validApprovals ?? 0),
    EvidenceFile: 'data/content/approvals/product-approval-decisions.json',
    Command: 'bun run approval:decisions && bun run approval:review-packet && bun run export:content',
    ClearsBlockerType: 'approval',
    CurrentBlockers: handoff.blockerSummary?.approval ?? 0,
    StopRule: 'All review acknowledgements and no-fake-evidence acknowledgement must be true.'
  },
  {
    Lane: 'Staging import logs',
    Owner: 'Lewis/Euan',
    StartCount: 3,
    DoneCount: Math.max(0, (staging.counts?.importLogs ?? 0)),
    RemainingCount: Math.max(0, 3 - (staging.counts?.importLogs ?? 0)),
    EvidenceFile: 'data/staging/import-logs/',
    Command: 'bun run staging:evidence',
    ClearsBlockerType: 'staging_evidence',
    CurrentBlockers: (staging.gates || []).filter((row: any) => String(row.Gate || '').startsWith('import_log') && row.Blocking === 'yes').length,
    StopRule: 'Logs must show failedRows=0 and successfulRows meeting expected row count.'
  },
  {
    Lane: 'PDP spot checks',
    Owner: 'Dashboard owner + Lewis/Euan',
    StartCount: 5,
    DoneCount: staging.counts?.passingPdpChecks ?? 0,
    RemainingCount: Math.max(0, 5 - (staging.counts?.passingPdpChecks ?? 0)),
    EvidenceFile: 'data/staging/pdp-checks/',
    Command: 'bun run staging:evidence',
    ClearsBlockerType: 'staging_evidence',
    CurrentBlockers: (staging.gates || []).some((row: any) => row.Gate === 'pdp_spot_checks' && row.Blocking === 'yes') ? 1 : 0,
    StopRule: 'At least 5 real staging PDP JSON checks, all checks=pass and no issues.'
  },
  {
    Lane: 'Cutover approval',
    Owner: 'Umar / JV',
    StartCount: 1,
    DoneCount: staging.counts?.cutoverApprovalPresent && !(staging.gates || []).some((row: any) => row.Gate === 'cutover_approval' && row.Blocking === 'yes') ? 1 : 0,
    RemainingCount: staging.counts?.cutoverApprovalPresent && !(staging.gates || []).some((row: any) => row.Gate === 'cutover_approval' && row.Blocking === 'yes') ? 0 : 1,
    EvidenceFile: 'data/staging/cutover-approval.json',
    Command: 'bun run staging:evidence && bun run verify:handoff',
    ClearsBlockerType: 'cutover',
    CurrentBlockers: (staging.gates || []).some((row: any) => row.Gate === 'cutover_approval' && row.Blocking === 'yes') ? 1 : 0,
    StopRule: 'Must be signed after import logs and PDP checks pass.'
  }
]

const totalRemaining = lanes.reduce((sum, row) => sum + Number(row.RemainingCount || 0), 0)
const totalStart = lanes.reduce((sum, row) => sum + Number(row.StartCount || 0), 0)
const totalDone = lanes.reduce((sum, row) => sum + Number(row.DoneCount || 0), 0)
const percentDone = totalStart ? Math.round((totalDone / totalStart) * 1000) / 10 : 0

const nextActions = lanes
  .filter(row => row.RemainingCount > 0)
  .map((row, index) => ({
    Sequence: index + 1,
    Lane: row.Lane,
    Owner: row.Owner,
    Remaining: row.RemainingCount,
    EvidenceFile: row.EvidenceFile,
    Command: row.Command,
    StopRule: row.StopRule
  }))

const manifest = {
  generatedAt,
  ready: totalRemaining === 0 && Boolean(handoff.readyForLewis) && Boolean(readiness.ready) && Boolean(staging.ready) && Boolean(verifier.ready),
  headline: totalRemaining === 0
    ? 'All burn-down lanes are complete; run final verification.'
    : `${totalRemaining} review/evidence items remain across ${lanes.filter(row => row.RemainingCount > 0).length} lanes before handoff can be ready.`,
  counts: {
    totalStart,
    totalDone,
    totalRemaining,
    percentDone,
    exportBlockers: handoff.counts?.blockers ?? null,
    verifierPassing: verifier.counts?.passing ?? null,
    verifierChecks: verifier.counts?.checks ?? null
  },
  lanes,
  nextActions
}

writeFileSync(join(outRoot, 'blocker_burndown.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf8')
writeFileSync(join(outRoot, 'blocker_burndown.csv'), csv(lanes, ['Lane', 'Owner', 'StartCount', 'DoneCount', 'RemainingCount', 'EvidenceFile', 'Command', 'ClearsBlockerType', 'CurrentBlockers', 'StopRule']), 'utf8')
writeFileSync(join(outRoot, 'blocker_burndown_next_actions.csv'), csv(nextActions, ['Sequence', 'Lane', 'Owner', 'Remaining', 'EvidenceFile', 'Command', 'StopRule']), 'utf8')
writeFileSync(join(outRoot, 'blocker_burndown.md'), [
  '# JV blocker burn-down',
  '',
  `Generated: ${generatedAt}`,
  '',
  `Headline: **${manifest.headline}**`,
  '',
  '## Progress',
  `- Total tracked items: ${totalStart}`,
  `- Done: ${totalDone}`,
  `- Remaining: ${totalRemaining}`,
  `- Percent done: ${percentDone}%`,
  `- Export blockers: ${manifest.counts.exportBlockers}`,
  `- Master verifier: ${manifest.counts.verifierPassing}/${manifest.counts.verifierChecks}`,
  '',
  '## Lanes',
  ...lanes.map(row => [
    `### ${row.Lane}`,
    `- Owner: ${row.Owner}`,
    `- Done / remaining: ${row.DoneCount} / ${row.RemainingCount}`,
    `- Evidence file: \`${row.EvidenceFile}\``,
    `- Command: \`${row.Command}\``,
    `- Stop rule: ${row.StopRule}`,
    ''
  ].join('\n')),
  '## Next actions',
  ...nextActions.map(row => `- ${row.Sequence}. ${row.Owner}: finish ${row.Remaining} item(s) in ${row.Lane}. Evidence: \`${row.EvidenceFile}\`.`),
  '',
  '## Guardrail',
  'This burn-down tracks explicit evidence, not intent. Counts only move when evidence files validate.',
  ''
].join('\n'), 'utf8')

console.log(`Blocker burn-down ready: ${manifest.ready}`)
console.log(`Remaining tracked items: ${totalRemaining}`)
if (!manifest.ready) process.exitCode = 1
