#!/usr/bin/env node
/**
 * Task #163 — Task Description Hygiene Pass
 *
 * Reads archived task markdown files from the ops manual, strips YAML
 * frontmatter, and emits a SQL file with UPDATE statements to backfill
 * descriptions for tasks in the `tasks` table.
 *
 * Run from Nitro (local) — outputs SQL for Michael to apply on dev panel.
 *
 * Usage:
 *   node scripts/backfill-task-descriptions.js
 *
 * Output:
 *   scripts/out/backfill-task-descriptions.sql
 *   scripts/out/backfill-task-descriptions-report.md
 */

const fs = require('fs');
const path = require('path');

const ARCHIVE_DIR = path.resolve(
  __dirname,
  '..',
  '..',
  'firefrost-operations-manual',
  'docs',
  'archive',
  'tasks-index-archived-2026-04-11'
);

const OUT_DIR = path.resolve(__dirname, 'out');

// 16 target tasks with empty descriptions (from REQ-2026-04-14-task-description-hygiene)
const TARGETS = [
  { num: 22,  title: 'Netdata Deployment' },
  { num: 23,  title: 'Department Structure & Access Control' },
  { num: 32,  title: 'Terraria Branding Arc' },
  { num: 48,  title: 'n8n Rebuild' },
  { num: 49,  title: 'NotebookLM Integration' },
  { num: 51,  title: 'Ignis Protocol' },
  { num: 81,  title: 'Memorial Writing Assistant' },
  { num: 89,  title: 'DERP Protocol Review' },
  { num: 97,  title: 'Trinity Console Social Hub' },
  { num: 99,  title: 'Multi-Lineage Claude Architecture' },
  { num: 100, title: 'Skill Index & Recommender System' },
  { num: 104, title: 'Server-Side Mod Deployment Automation' },
  { num: 105, title: 'Trinity Console Review Workflow' },
  { num: 106, title: 'Minecraft Log Analyzer Bot' },
  { num: 113, title: 'Claude Projects Architecture' }
];

function stripFrontmatter(raw) {
  // YAML frontmatter is the first block between --- ... ---
  if (!raw.startsWith('---')) return raw.trim();
  const end = raw.indexOf('\n---', 3);
  if (end < 0) return raw.trim();
  return raw.slice(end + 4).replace(/^\s*\n/, '').trim();
}

function sqlEscape(s) {
  // Postgres dollar-quoted string — safest for markdown bodies
  // Use a tag unlikely to appear in content
  return `$body$${s}$body$`;
}

function indexArchive() {
  if (!fs.existsSync(ARCHIVE_DIR)) {
    console.error(`Archive dir not found: ${ARCHIVE_DIR}`);
    process.exit(1);
  }
  const files = fs.readdirSync(ARCHIVE_DIR).filter(f => /^task-\d+-.+\.md$/.test(f));
  const byNum = new Map();
  for (const f of files) {
    const m = f.match(/^task-(\d+)-/);
    if (!m) continue;
    byNum.set(parseInt(m[1], 10), f);
  }
  return byNum;
}

function main() {
  fs.mkdirSync(OUT_DIR, { recursive: true });

  const archiveIndex = indexArchive();
  const matched = [];
  const missing = [];

  for (const t of TARGETS) {
    const file = archiveIndex.get(t.num);
    if (!file) {
      missing.push(t);
      continue;
    }
    const raw = fs.readFileSync(path.join(ARCHIVE_DIR, file), 'utf8');
    const body = stripFrontmatter(raw);
    matched.push({ ...t, file, body });
  }

  // Emit SQL
  const sqlLines = [
    '-- Task #163 — Task Description Hygiene Pass',
    '-- Generated: ' + new Date().toISOString(),
    '-- Source: firefrost-operations-manual/docs/archive/tasks-index-archived-2026-04-11/',
    `-- Matched: ${matched.length}/${TARGETS.length}  Missing: ${missing.length}`,
    '',
    'BEGIN;',
    ''
  ];
  for (const m of matched) {
    sqlLines.push(`-- Task #${m.num}: ${m.title}  (from ${m.file})`);
    sqlLines.push(
      `UPDATE tasks SET description = ${sqlEscape(m.body)}, updated_at = NOW() ` +
      `WHERE task_number = ${m.num} AND (description IS NULL OR description = '');`
    );
    sqlLines.push('');
  }
  sqlLines.push('COMMIT;', '');

  const sqlPath = path.join(OUT_DIR, 'backfill-task-descriptions.sql');
  fs.writeFileSync(sqlPath, sqlLines.join('\n'));

  // Emit report
  const report = [
    '# Task #163 — Backfill Report',
    '',
    `**Generated:** ${new Date().toISOString()}`,
    `**Matched:** ${matched.length}/${TARGETS.length}`,
    `**Missing:** ${missing.length}`,
    '',
    '## Matched (SQL UPDATE emitted)',
    '',
    '| # | Title | Source file |',
    '|---|-------|-------------|',
    ...matched.map(m => `| ${m.num} | ${m.title} | \`${m.file}\` |`),
    '',
    '## Missing (no archive file — needs manual description)',
    '',
    missing.length === 0
      ? '_(none)_'
      : ['| # | Title |', '|---|-------|', ...missing.map(m => `| ${m.num} | ${m.title} |`)].join('\n'),
    ''
  ].join('\n');

  const reportPath = path.join(OUT_DIR, 'backfill-task-descriptions-report.md');
  fs.writeFileSync(reportPath, report);

  console.log(`Matched ${matched.length}/${TARGETS.length}. Missing ${missing.length}.`);
  console.log(`SQL:    ${sqlPath}`);
  console.log(`Report: ${reportPath}`);
}

main();
