#!/usr/bin/env node
/**
 * cli:extract-doc — read-only extraction for the /documentation skill.
 *
 * Emits an ExecuteEnvelope on stdout and writes NO files. Claude reads the
 * `report` to author a faithful doc page, then calls scaffold-doc (i18n +
 * wiring) and ui-polish (theme tokens).
 *
 * Usage:
 *   npx tsx skills/documentation/cli/extract-doc/index.ts \
 *     --spec '{"type":"user","target":"users","application":"administration","projectPath":"/abs/path"}'
 */
import { parseArgs } from 'node:util'
import { validate } from './validate.js'
import { extract } from './extract.js'
import { executeEnvelope, failExecute, printEnvelope } from '../../../lib/output.js'
import type { ExtractDocInput, ExtractReport } from './types.js'

const COMMAND = 'extract-doc'

async function main(): Promise<void> {
  const { values } = parseArgs({ options: { spec: { type: 'string' } }, strict: true })
  if (!values.spec) {
    printEnvelope(failExecute(COMMAND, ['--spec is required']))
    process.exit(1)
  }
  let raw: unknown
  try {
    raw = JSON.parse(values.spec)
  } catch {
    printEnvelope(failExecute(COMMAND, ['Invalid JSON in --spec']))
    process.exit(1)
  }
  const validation = validate(raw)
  if (!validation.valid) {
    printEnvelope(failExecute(COMMAND, validation.errors))
    process.exit(1)
  }
  const warnings = [...validation.warnings]
  try {
    const report = await extract(raw as ExtractDocInput, warnings)
    printEnvelope(executeEnvelope<ExtractReport>(COMMAND, { report, warnings, nextSteps: buildNextSteps(report) }))
  } catch (err) {
    printEnvelope(failExecute(COMMAND, [err instanceof Error ? err.message : String(err)]))
    process.exit(1)
  }
}

function buildNextSteps(report: ExtractReport): string[] {
  const steps: string[] = []

  // Corrective gate (two mirror checks): surface forbidden "sales" framing to
  // strip AND a missing mandatory "objective" to add. The step-03 gate re-runs
  // this same scan and blocks until the doc is both clean and complete.
  const forbidden = report.existingDoc.forbiddenSections
  if (forbidden.length > 0) {
    const locations = forbidden.map((f) => `${f.file}:${f.line} (${f.token})`).join(', ')
    steps.push(
      `EXISTING doc contains forbidden problème/solution / Bénéfices / Avant-Après sections at ${locations} — ` +
        `REMOVE them while regenerating. Do NOT re-author the benefits/beforeAfter/problem/solution keys ` +
        `(the doc leads with a factual "objective", not a sales pitch). The step-03 gate re-runs this scan and blocks until clean.`,
    )
  }
  const missing = report.existingDoc.missingRequired
  if (missing.includes('objective')) {
    steps.push(
      `EXISTING doc has NO "Objectif" section — the mandatory Section 1 (a short factual description of what the ` +
        `module does, written as an objective). ADD it FIRST as its own section: author the i18n keys ` +
        `"sections.objective" + "objective" (user) or "overview.objective" (DocRenderer) and render t('objective'). ` +
        `The header subtitle is NOT a substitute. The step-03 gate re-runs this scan and blocks until present.`,
    )
  }
  if (missing.includes('summary')) {
    steps.push(
      `EXISTING user doc has NO header accent tagline — the one-line accent summary between the title and the ` +
        `subtitle. ADD the i18n key "summary" and render it as <p class="text-xl text-[var(--color-accent-600)] ` +
        `font-medium">{t('summary')}</p>, then the stats line (N {t('header.businessRules')} · N {t('header.apiEndpoints')} · …, ` +
        `count as plain sibling text, NOT pills). The step-03 gate blocks until present.`,
    )
  }

  if (report.type === 'user') {
    steps.push(
      report.resolved.pageTsxPath
        ? `Read ${report.resolved.pageTsxPath} and reproduce it faithfully as annotated Mock UI (do NOT invent a generic table/KPI layout).`
        : 'No real page found under src/pages — author the Mock UI from the live app or the pagespec.',
    )
    if (report.charts.length > 0) {
      steps.push(
        `Match each chart TYPE: ${report.charts
          .map((c) => `${c.component} → ${c.mockUiPattern}`)
          .join(' | ')}`,
      )
    }
  }
  steps.push(
    'Then call scaffold-doc to write the i18n files (4 langs) + wire routes/manifest/config, and run ui-polish to enforce theme tokens.',
  )
  return steps
}

void main()
