#!/usr/bin/env node
/**
 * scaffold-screen-controller — index.ts
 *
 * Reads pagespecs/<Entity>.<view>.md filtered by (section, entity), generates
 * the {EntityPlural}ScreenController.cs + one {Entity}{View}ScreenDto per
 * read screen, and writes them under spec.projectPath. Returns a JSON
 * envelope on stdout (success | error | files generated count | todos).
 *
 * Exit code 0 on success, 1 on filesystem/parse failure, 2 on invalid spec.
 */

import { parseArgs } from 'node:util'
import { mkdirSync, writeFileSync } from 'node:fs'
import { dirname, join, resolve } from 'node:path'
import { generate } from './generate.js'
import { parsePagespecsForSection } from './parse-pagespec.js'
import type { Result } from './types.js'
import { validate } from './validate.js'

async function main(): Promise<void> {
  const args = parseArgs({
    options: {
      spec: { type: 'string' },
      json: { type: 'boolean', default: false },
    },
    allowPositionals: false,
  })

  if (!args.values.spec) {
    console.error('Error: --spec is required')
    process.exit(2)
  }

  let raw: unknown
  try {
    raw = JSON.parse(args.values.spec)
  } catch {
    console.error('Error: --spec must be valid JSON')
    process.exit(2)
  }

  const v = validate(raw)
  if (!v.valid) {
    emit(args.values.json, {
      success: false,
      error: v.errors.join('; '),
      filesGenerated: 0,
      files: [],
      todos: [],
    })
    process.exit(2)
  }
  const spec = v.data!

  // Parse pagespecs filtered to (section, entity).
  const { pagespecs, warnings } = parsePagespecsForSection(spec.moduleDir, spec.section, spec.entity)

  if (pagespecs.length === 0) {
    emit(args.values.json, {
      success: false,
      error: `No pagespecs found in ${spec.moduleDir}/pagespecs/ matching section="${spec.section}" entity="${spec.entity}". Warnings: ${warnings.map(w => `${w.file}: ${w.reason}`).join('; ') || '(none)'}`,
      filesGenerated: 0,
      files: [],
      todos: [],
    })
    process.exit(1)
  }

  // Generate + write
  const out = generate(spec, pagespecs)
  for (const f of out.files) {
    const abs = resolve(join(spec.projectPath, f.path))
    mkdirSync(dirname(abs), { recursive: true })
    writeFileSync(abs, f.content, 'utf8')
  }

  emit(args.values.json, {
    success: true,
    filesGenerated: out.files.length,
    files: out.files,
    todos: out.todos,
  })
  process.exit(0)
}

function emit(json: boolean | undefined, payload: Result): void {
  if (json) {
    console.log(JSON.stringify(payload, null, 2))
    return
  }
  if (!payload.success) {
    console.error(`✗ ${payload.error}`)
    return
  }
  console.log(`✓ scaffold-screen-controller: ${payload.filesGenerated} file(s) generated`)
  for (const f of payload.files) console.log(`  - ${f.path}`)
  if (payload.todos.length > 0) {
    console.log('')
    console.log(`  TODOs (${payload.todos.length}):`)
    for (const t of payload.todos) console.log(`    - ${t}`)
  }
}

main().catch(err => {
  console.error('Fatal:', (err as Error).message)
  process.exit(2)
})
