import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import {
  mkdtempSync,
  mkdirSync,
  writeFileSync,
  readFileSync,
  existsSync,
  rmSync,
  cpSync,
} from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { HeadlessPrompter } from '../../src/prompter/headless-prompter.js';
import { createConfigService } from '../../src/config/config-service.js';
import { runWizard } from '../../src/wizard.js';

describe('Full Wizard (headless)', () => {
  let tmpDir: string;
  const repoRoot = join(import.meta.dirname, '..', '..');
  const originalEnv = { ...process.env };

  beforeEach(() => {
    tmpDir = mkdtempSync(join(tmpdir(), 'mosaic-wizard-test-'));
    // Copy templates to tmp dir — templates live under framework/ after monorepo migration
    const candidates = [join(repoRoot, 'framework', 'templates'), join(repoRoot, 'templates')];
    for (const templatesDir of candidates) {
      if (existsSync(templatesDir)) {
        cpSync(templatesDir, join(tmpDir, 'templates'), { recursive: true });
        break;
      }
    }
  });

  afterEach(() => {
    rmSync(tmpDir, { recursive: true, force: true });
    process.env = { ...originalEnv };
  });

  it('quick start produces valid SOUL.md', async () => {
    // The headless path reads agent name from MOSAIC_AGENT_NAME env var
    // (via agentIntentStage) rather than prompting interactively.
    process.env['MOSAIC_AGENT_NAME'] = 'TestBot';

    const prompter = new HeadlessPrompter({
      'Installation mode': 'quick',
      'Communication style': 'direct',
      'Your name': 'Tester',
      'Your pronouns': 'They/Them',
      'Your timezone': 'UTC',
    });

    await runWizard({
      mosaicHome: tmpDir,
      sourceDir: tmpDir,
      prompter,
      configService: createConfigService(tmpDir, tmpDir),
      skipGateway: true,
    });

    const soulPath = join(tmpDir, 'SOUL.md');
    expect(existsSync(soulPath)).toBe(true);

    const soul = readFileSync(soulPath, 'utf-8');
    expect(soul).toContain('You are **TestBot**');
    expect(soul).toContain('Be direct, concise, and concrete');
    expect(soul).toContain('execution partner and visibility engine');
  });

  it('quick start produces valid USER.md', async () => {
    process.env['MOSAIC_AGENT_NAME'] = 'TestBot';

    const prompter = new HeadlessPrompter({
      'Installation mode': 'quick',
      'Communication style': 'direct',
      'Your name': 'Tester',
      'Your pronouns': 'He/Him',
      'Your timezone': 'America/Chicago',
    });

    await runWizard({
      mosaicHome: tmpDir,
      sourceDir: tmpDir,
      prompter,
      configService: createConfigService(tmpDir, tmpDir),
      skipGateway: true,
    });

    const userPath = join(tmpDir, 'USER.md');
    expect(existsSync(userPath)).toBe(true);

    const user = readFileSync(userPath, 'utf-8');
    expect(user).toContain('**Name:** Tester');
    expect(user).toContain('**Pronouns:** He/Him');
    expect(user).toContain('**Timezone:** America/Chicago');
  });

  it('applies CLI overrides', async () => {
    const prompter = new HeadlessPrompter({
      'Installation mode': 'quick',
      'Your name': 'FromPrompt',
    });

    await runWizard({
      mosaicHome: tmpDir,
      sourceDir: tmpDir,
      prompter,
      configService: createConfigService(tmpDir, tmpDir),
      skipGateway: true,
      cliOverrides: {
        soul: {
          agentName: 'FromCLI',
          communicationStyle: 'formal',
        },
      },
    });

    const soul = readFileSync(join(tmpDir, 'SOUL.md'), 'utf-8');
    expect(soul).toContain('You are **FromCLI**');
    expect(soul).toContain('Use professional, structured language');
  });
});
