import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import type { WizardPrompter } from '../prompter/interface.js';
import type { ConfigService } from '../config/config-service.js';
import type { WizardState, InstallAction } from '../types.js';

function detectExistingInstall(mosaicHome: string): boolean {
  if (!existsSync(mosaicHome)) return false;
  return (
    existsSync(join(mosaicHome, 'bin/mosaic')) ||
    existsSync(join(mosaicHome, 'AGENTS.md')) ||
    existsSync(join(mosaicHome, 'SOUL.md'))
  );
}

function detectExistingIdentity(mosaicHome: string): {
  hasSoul: boolean;
  hasUser: boolean;
  hasTools: boolean;
  agentName?: string;
} {
  const soulPath = join(mosaicHome, 'SOUL.md');
  const hasSoul = existsSync(soulPath);
  let agentName: string | undefined;

  if (hasSoul) {
    try {
      const content = readFileSync(soulPath, 'utf-8');
      const match = content.match(/You are \*\*(.+?)\*\*/);
      agentName = match?.[1];
    } catch {
      // Non-fatal
    }
  }

  return {
    hasSoul,
    hasUser: existsSync(join(mosaicHome, 'USER.md')),
    hasTools: existsSync(join(mosaicHome, 'TOOLS.md')),
    agentName,
  };
}

export async function detectInstallStage(
  p: WizardPrompter,
  state: WizardState,
  config: ConfigService,
): Promise<void> {
  const existing = detectExistingInstall(state.mosaicHome);
  if (!existing) {
    state.installAction = 'fresh';
    return;
  }

  const identity = detectExistingIdentity(state.mosaicHome);
  const identitySummary = identity.agentName
    ? `Agent: ${identity.agentName}`
    : 'No identity configured';

  p.note(
    `Found existing Mosaic installation at:\n${state.mosaicHome}\n\n` +
      `${identitySummary}\n` +
      `SOUL.md: ${identity.hasSoul ? 'yes' : 'no'}\n` +
      `USER.md: ${identity.hasUser ? 'yes' : 'no'}\n` +
      `TOOLS.md: ${identity.hasTools ? 'yes' : 'no'}`,
    'Existing Installation Detected',
  );

  state.installAction = await p.select<InstallAction>({
    message: 'What would you like to do?',
    options: [
      {
        value: 'keep',
        label: 'Keep identity, update framework',
        hint: 'Preserves SOUL.md, USER.md, TOOLS.md, memory/',
      },
      {
        value: 'reconfigure',
        label: 'Reconfigure identity',
        hint: 'Re-run identity setup, update framework',
      },
      {
        value: 'reset',
        label: 'Fresh install',
        hint: 'Replace everything',
      },
    ],
  });

  if (state.installAction === 'keep' || state.installAction === 'reconfigure') {
    // Load existing values — for 'keep' they're final, for 'reconfigure'
    // they become pre-populated defaults so the user can tweak them.
    state.soul = await config.readSoul();
    state.user = await config.readUser();
    state.tools = await config.readTools();
  }
}
