import type { Prompter } from './prompts.js';
import type { ConfigBuilder } from './config.js';

const GOOGLE_SETUP_INSTRUCTIONS = [
  '  To set up Google API access:',
  '  1. Go to https://console.cloud.google.com → create or select a project',
  '  2. Enable the required APIs (see below)',
  '  3. Go to APIs & Services → Credentials → Create Credentials → OAuth client ID',
  '  4. Choose "Desktop app", download the JSON file',
  '  5. Save it as ~/.config/flynn/gmail-credentials.json (or a path of your choice)',
];

interface GoogleService {
  name: string;
  configKey: string;
  apis: string[];
  authCmd: string;
  setter: (builder: ConfigBuilder, creds: string) => void;
}

const GOOGLE_SERVICES: GoogleService[] = [
  {
    name: 'Gmail',
    configKey: 'gmail',
    apis: ['Gmail API'],
    authCmd: 'gmail-auth',
    setter: (b, c) => b.setGmailEnabled(c, 'webchat', 'gmail'),
  },
  {
    name: 'Google Calendar',
    configKey: 'gcal',
    apis: ['Google Calendar API'],
    authCmd: 'gcal-auth',
    setter: (b, c) => b.setGcalEnabled(c),
  },
  {
    name: 'Google Docs',
    configKey: 'gdocs',
    apis: ['Google Docs API', 'Google Drive API'],
    authCmd: 'gdocs-auth',
    setter: (b, c) => b.setGdocsEnabled(c),
  },
  {
    name: 'Google Drive',
    configKey: 'gdrive',
    apis: ['Google Drive API'],
    authCmd: 'gdrive-auth',
    setter: (b, c) => b.setGdriveEnabled(c),
  },
  {
    name: 'Google Tasks',
    configKey: 'gtasks',
    apis: ['Google Tasks API'],
    authCmd: 'gtasks-auth',
    setter: (b, c) => b.setGtasksEnabled(c),
  },
];

export async function setupAutomation(p: Prompter, builder: ConfigBuilder): Promise<void> {
  const cron = await p.confirm('Enable cron scheduler?', false);
  if (cron) {
    builder.setCronEnabled();
    p.println('✓ Cron enabled — add jobs to config.yaml under automation.cron.jobs[]');
  }

  const webhooks = await p.confirm('Enable webhook receiver?', false);
  if (webhooks) {
    p.println('  Webhooks accept HTTP POST at /webhooks/:name on the gateway port.');
    p.println('  Set a shared secret to verify requests via HMAC signature.');
    const secret = await p.ask('Webhook shared secret (optional)', '');
    builder.setWebhooksEnabled(secret || undefined);
    p.println('✓ Webhooks enabled — define triggers in config.yaml under automation.webhooks[]');
  }

  // Google services
  const wantGoogle = await p.confirm('Configure Google services (Gmail, Calendar, Docs, Drive, Tasks)?', false);
  if (!wantGoogle) {return;}

  p.println();
  for (const line of GOOGLE_SETUP_INSTRUCTIONS) {
    p.println(line);
  }
  p.println();

  const creds = await p.ask('OAuth credentials file', '~/.config/flynn/gmail-credentials.json');
  p.println();

  const enabledServices: GoogleService[] = [];

  for (const service of GOOGLE_SERVICES) {
    const enable = await p.confirm(`Enable ${service.name}?`, false);
    if (enable) {
      service.setter(builder, creds);
      const apis = service.apis.join(', ');
      p.println(`✓ ${service.name} enabled (requires: ${apis})`);
      enabledServices.push(service);
    }
  }

  if (enabledServices.length > 0) {
    p.println();
    p.println('After saving config, authenticate each service:');
    for (const svc of enabledServices) {
      p.println(`  flynn ${svc.authCmd}`);
    }
  }
}

/**
 * Run OAuth auth flows for enabled Google services.
 * Called after config is saved so the auth commands can read it.
 */
export async function runGoogleAuth(p: Prompter, config: Record<string, any>): Promise<void> {
  const automation = config.automation as Record<string, any> | undefined;
  if (!automation) {return;}

  const pending: { name: string; authCmd: string }[] = [];
  for (const svc of GOOGLE_SERVICES) {
    const svcConfig = automation[svc.configKey] as { enabled?: boolean } | undefined;
    if (svcConfig?.enabled) {
      pending.push({ name: svc.name, authCmd: svc.authCmd });
    }
  }

  if (pending.length === 0) {return;}

  p.println();
  const runAuth = await p.confirm(`Run OAuth authentication for ${pending.map(s => s.name).join(', ')}?`, true);
  if (!runAuth) {
    p.println('Skipped. Run these commands later:');
    for (const svc of pending) {
      p.println(`  flynn ${svc.authCmd}`);
    }
    return;
  }

  const { execFileSync } = await import('child_process');

  for (const svc of pending) {
    p.println();
    p.println(`Authenticating ${svc.name}...`);
    try {
      execFileSync(process.execPath, [process.argv[1], svc.authCmd], {
        stdio: 'inherit',
      });
      p.println(`✓ ${svc.name} authenticated`);
    } catch {
      p.println(`✗ ${svc.name} auth failed — run "flynn ${svc.authCmd}" manually`);
    }
  }
}
