/**
 * Full-Flow Test Report Utility
 *
 * Plain console.log formatters for human-readable output at each stage of the
 * full-flow integration test. No external dependencies.
 */

import { execSync } from 'node:child_process';
import { join } from 'node:path';
import type { Phase, Task } from '../../../db/schema.js';
import type { AgentResult } from '../../../agent/types.js';

// =============================================================================
// Types
// =============================================================================

export interface ExecutedTask {
  task: Task;
  result: AgentResult | null;
}

// =============================================================================
// Helpers
// =============================================================================

const DIVIDER = '═'.repeat(60);
const THIN = '─'.repeat(60);

function section(title: string): void {
  console.log(`\n${DIVIDER}`);
  console.log(`  ${title}`);
  console.log(DIVIDER);
}

function line(msg: string): void {
  console.log(`  ${msg}`);
}

// =============================================================================
// Stage reporters
// =============================================================================

export function printHeader(initiativeName: string): void {
  section(`FULL-FLOW TEST: ${initiativeName}`);
  console.log(`  Started at: ${new Date().toISOString()}`);
}

export function printDiscussResult(agentId: string, result: AgentResult | null): void {
  console.log(`\n[DISCUSS]`);
  console.log(THIN);
  line(`Agent: ${agentId}`);
  if (result) {
    line(`Success: ${result.success}`);
    if (result.message) line(`Message: ${result.message.slice(0, 200)}`);
  } else {
    line('Result: null (agent may have crashed)');
  }
}

export function printPlanResult(phases: Phase[]): void {
  console.log(`\n[PLAN] ${phases.length} phase(s) created`);
  console.log(THIN);
  phases.forEach((ph, i) => {
    line(`${i + 1}. ${ph.name}`);
  });
}

export function printDetailResult(phase: Phase, tasks: Task[]): void {
  console.log(`\n[DETAIL] Phase "${phase.name}" → ${tasks.length} task(s)`);
  console.log(THIN);
  tasks.forEach((t, i) => {
    const flags = [t.category, t.type].join(', ');
    line(`${i + 1}. ${t.name} [${flags}]`);
    if (t.description) {
      line(`   ${t.description.slice(0, 120)}`);
    }
  });
}

export function printExecuteResult(executed: ExecutedTask[]): void {
  const succeeded = executed.filter((e) => e.result?.success).length;
  console.log(`\n[EXECUTE] ${succeeded}/${executed.length} task(s) succeeded`);
  console.log(THIN);
  for (const { task, result } of executed) {
    const icon = result?.success ? '✓' : '✗';
    line(`${icon} ${task.name}`);
    if (result && !result.success) {
      line(`  Error: ${result.message?.slice(0, 120)}`);
    }
  }
}

export function printGitDiff(workspaceRoot: string, projectName: string): void {
  console.log('\n[GIT DIFF — agent worktrees]');
  console.log(THIN);

  // Find all agent worktrees for this project
  const worktreesBase = join(workspaceRoot, 'agent-workdirs');
  try {
    const dirs = execSync(`ls "${worktreesBase}" 2>/dev/null || echo ""`, { encoding: 'utf8' })
      .trim()
      .split('\n')
      .filter(Boolean);

    for (const dir of dirs) {
      const projectDir = join(worktreesBase, dir, projectName);
      try {
        const stat = execSync(`git -C "${projectDir}" diff HEAD~1 --stat 2>/dev/null || echo ""`, {
          encoding: 'utf8',
        }).trim();
        if (stat) {
          line(`Worktree: ${dir}/${projectName}`);
          stat.split('\n').forEach((l) => line(`  ${l}`));
        }
      } catch {
        // Worktree might not have commits — skip silently
      }
    }
  } catch {
    line('(no agent worktrees found)');
  }
}

export function printNpmTestResult(projectDir: string): void {
  console.log('\n[NPM TEST]');
  console.log(THIN);
  try {
    const output = execSync('node --test src/todo.test.js', {
      cwd: projectDir,
      encoding: 'utf8',
      stdio: ['ignore', 'pipe', 'pipe'],
    });
    line('Tests passed:');
    output.split('\n').forEach((l) => line(`  ${l}`));
  } catch (err: unknown) {
    const e = err as { stdout?: string; stderr?: string; status?: number };
    line(`Tests FAILED (exit ${e.status ?? '?'})`);
    if (e.stdout) e.stdout.split('\n').forEach((l) => line(`  ${l}`));
    if (e.stderr) e.stderr.split('\n').forEach((l) => line(`  ${l}`));
  }
}

export function printFinalSummary(
  initiativeName: string,
  phases: Phase[],
  tasks: Task[],
  executed: ExecutedTask[],
  durationMs: number,
): void {
  section(`SUMMARY: ${initiativeName}`);
  line(`Duration : ${Math.round(durationMs / 1000)}s`);
  line(`Phases   : ${phases.length}`);
  line(`Tasks    : ${tasks.length}`);
  line(`Executed : ${executed.filter((e) => e.result?.success).length}/${executed.length} succeeded`);
  console.log(DIVIDER);
}
