import { writeFile } from 'node:fs/promises'
import process from 'node:process'
import { Command } from 'commander'
import { logger } from '../../core/logger.ts'
import { DAEMON_BASE_URL } from '../../core/paths.ts'
import { formatHtml } from '../format/html.ts'
import { formatMarkdown } from '../format/markdown.ts'
import { redactDeep } from '../format/redact.ts'

type ReportOptions = {
  format: string
  output?: string
  redact: boolean
}

export const reportCommand = new Command('report')
  .description('Generate a shareable run report.')
  .argument('<run-id>', 'Run ID to report on.')
  .option('--format <fmt>', "'md' | 'json' | 'html'", 'md')
  .option('--output <file>', 'Default: stdout.')
  .option(
    '--redact',
    'Mask anything that looks like a credential (API keys, bearer tokens).',
    false,
  )
  .action(async (runId: string, options: ReportOptions) => {
    if (options.format !== 'md' && options.format !== 'json' && options.format !== 'html') {
      logger.print(`Unknown --format: ${options.format} (expected 'md', 'json', or 'html')`)
      process.exitCode = 2
      return
    }

    const url = `${DAEMON_BASE_URL}/api/runs/${encodeURIComponent(runId)}`
    let res: Response
    try {
      res = await fetch(url, { signal: AbortSignal.timeout(5000) })
    } catch {
      logger.print('Daemon not reachable. Start it with `openthomas wire` or `openthomas daemon`.')
      process.exitCode = 1
      return
    }
    if (res.status === 404) {
      logger.print(`Run not found: ${runId}`)
      process.exitCode = 1
      return
    }
    if (!res.ok) {
      logger.print(`Daemon error: HTTP ${res.status}`)
      process.exitCode = 1
      return
    }

    // biome-ignore lint/suspicious/noExplicitAny: validated by daemon
    const detail = (await res.json()) as any

    let output: string
    if (options.format === 'json') {
      const payload = options.redact ? redactDeep(detail) : detail
      output = `${JSON.stringify(payload, null, 2)}\n`
    } else if (options.format === 'html') {
      output = formatHtml(detail, { redact: options.redact })
    } else {
      output = formatMarkdown(detail, { redact: options.redact })
    }

    if (options.output) {
      await writeFile(options.output, output)
      logger.print(`wrote ${output.length} bytes to ${options.output}`)
    } else {
      process.stdout.write(output)
    }
  })
