/**
 * Flow Prompt Generator
 *
 * Generates the AI prompt that drives the autonomous development loop.
 * When a user runs `/flow <intent>`, this creates a structured prompt
 * that instructs the AI to:
 * 1. Generate a spec from the intent
 * 2. Present it for user approval
 * 3. Decompose into a plan
 * 4. Implement each step with verification
 * 5. Fix failures within iteration bounds
 * 6. Save checkpoints
 */

import {
  startFlow,
  generateFlowSpec,
  getActiveFlow,
} from '../../services/FlowEngine/FlowEngine.js'
import { initForge } from '../../services/Forge/ForgeDaemon.js'
import { findMatchingInstincts } from '../../services/InstinctEngine/instinctStore.js'

/**
 * Generate the autonomous loop prompt for a flow intent.
 */
export async function generateFlowPrompt(intent: string): Promise<string> {
  const lines: string[] = []

  // Check for existing flow
  const existing = getActiveFlow()
  if (existing) {
    return [
      `A flow is already active: ${existing.id}`,
      `Intent: ${existing.intent}`,
      `Status: ${existing.status}`,
      '',
      'Use /flowctl stop to end it, or /flowctl status to see progress.',
    ].join('\n')
  }

  // Initialize Forge
  let forgeInfo = 'Forge: not configured'
  try {
    const forgeConfig = await initForge()
    forgeInfo = `Forge initialized: test command is "${forgeConfig.testCommand}"`
  } catch {
    forgeInfo = 'Forge: Could not auto-detect test command. You may need to run tests manually.'
  }

  // Find matching instincts
  const matchingInstincts = await findMatchingInstincts(intent)
  const instinctSection = matchingInstincts.length > 0
    ? [
        '',
        '## Relevant Instincts (learned patterns from past sessions)',
        '',
        ...matchingInstincts.slice(0, 5).map(i =>
          `- **${i.name}** (${(i.confidence * 100).toFixed(0)}% confidence, used ${i.usageCount}x): ${i.steps.slice(0, 2).join('; ')}`
        ),
        '',
        'Apply these instincts when relevant. They represent patterns that worked in similar tasks before.',
      ].join('\n')
    : ''

  // Start the flow
  const state = await startFlow(intent)

  // Generate the spec
  let specSection = ''
  try {
    const spec = await generateFlowSpec(state)
    state.spec = spec

    specSection = [
      '',
      '## Generated Specification',
      '',
      `**Type:** ${spec.type}`,
      `**Risk:** ${spec.risk}`,
      `**Estimated files:** ${spec.scope.estimatedFiles}`,
      '',
      '### Requirements',
      ...spec.requirements.map(r => `- ${r}`),
      '',
      '### Acceptance Criteria',
      ...spec.acceptanceCriteria.map(c => `- [ ] ${c.description} _(verify: ${c.verificationMethod})_`),
      '',
      ...(spec.edgeCases.length > 0 ? [
        '### Edge Cases',
        ...spec.edgeCases.map(e => `- ${e}`),
        '',
      ] : []),
    ].join('\n')
  } catch (e) {
    specSection = `\nSpec generation encountered an issue: ${e instanceof Error ? e.message : String(e)}\nProceed with your best understanding of the intent.\n`
  }

  // Build the full autonomous loop prompt
  lines.push(`# SANDCODE Flow — Autonomous Development Loop`)
  lines.push('')
  lines.push(`**Flow ID:** ${state.id}`)
  lines.push(`**Intent:** ${intent}`)
  lines.push(`**${forgeInfo}**`)
  lines.push(instinctSection)
  lines.push(specSection)
  lines.push('---')
  lines.push('')
  lines.push('## Your Task')
  lines.push('')
  lines.push('You are now in autonomous development mode. Follow this loop precisely:')
  lines.push('')
  lines.push('### Phase 1: Plan (if not already planned)')
  lines.push('- Break the specification above into concrete implementation steps')
  lines.push('- Each step should be small, testable, and independent where possible')
  lines.push('- Identify which files to create or modify for each step')
  lines.push('')
  lines.push('### Phase 2: Implement-Verify-Fix Loop')
  lines.push('For each step:')
  lines.push('1. **Implement** — Make focused, minimal changes to accomplish the step')
  lines.push('2. **Verify** — Run tests to confirm the step works (use Bash to run the test command)')
  lines.push('3. **Fix** — If tests fail, analyze the error, fix it, and re-verify (max 5 attempts per step)')
  lines.push('4. **Checkpoint** — After each step passes, briefly summarize what was done')
  lines.push('')
  lines.push('### Phase 3: Final Verification')
  lines.push('- Run the full test suite')
  lines.push('- Verify all acceptance criteria are met')
  lines.push('- Check for lint/type errors')
  lines.push('- Report the final result')
  lines.push('')
  lines.push('### Rules')
  lines.push('- Make MINIMAL changes. Do not refactor unrelated code.')
  lines.push('- After each implementation step, run tests BEFORE moving on.')
  lines.push('- If a step fails 5 times, report the issue and ask for guidance rather than continuing to retry.')
  lines.push('- Do NOT modify tests to make them pass — fix the implementation.')
  lines.push('- Save work frequently — if something goes wrong, the user can use `/flowctl checkpoints` to roll back.')
  lines.push('- When all steps are done, output a summary of what was built and any manual follow-up needed.')
  lines.push('')
  lines.push('### Status Updates')
  lines.push('Use `/flowctl status` at any time to check flow progress.')
  lines.push('Use `/flowctl stop` to pause the flow (it can be resumed with `/flowctl resume`).')
  lines.push('')
  lines.push('Begin now. Start with Phase 1 if the spec needs more detail, or go straight to Phase 2 if the steps above are clear.')

  return lines.join('\n')
}
