import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { homedir, platform } from 'node:os';
import { execa } from 'execa';

export interface ExtractedAccount {
  email: string;
  accountUuid: string;
  configJson: object;
  credentials: string;
}

/**
 * Resolve the Claude Code config path with fallback logic.
 * Primary: ~/.claude/.claude.json (if it exists and has oauthAccount)
 * Fallback: ~/.claude.json
 */
function getClaudeConfigPath(): string {
  const home = homedir();
  const primary = join(home, '.claude', '.claude.json');
  const fallback = join(home, '.claude.json');

  if (existsSync(primary)) {
    try {
      const json = JSON.parse(readFileSync(primary, 'utf-8'));
      if (json.oauthAccount) return primary;
    } catch {
      // invalid JSON, fall through
    }
  }

  return fallback;
}

export async function extractCurrentClaudeAccount(): Promise<ExtractedAccount> {
  const home = homedir();

  // 1. Read Claude config (with fallback logic matching ccswitch)
  const configPath = getClaudeConfigPath();
  const configRaw = readFileSync(configPath, 'utf-8');
  const configJson = JSON.parse(configRaw);

  const email = configJson.oauthAccount?.emailAddress;
  const accountUuid = configJson.oauthAccount?.accountUuid;

  if (!email || !accountUuid) {
    throw new Error('No Claude account found. Please log in with `claude` first.');
  }

  // 2. Read credentials (platform-specific)
  let credentials: string;
  if (platform() === 'darwin') {
    // macOS: read from Keychain
    const { stdout } = await execa('security', [
      'find-generic-password',
      '-s', 'Claude Code-credentials',
      '-w',
    ]);
    credentials = stdout;
  } else {
    // Linux: read from file
    const credPath = join(home, '.claude', '.credentials.json');
    credentials = readFileSync(credPath, 'utf-8');
  }

  return { email, accountUuid, configJson, credentials };
}
