import type { Command } from 'commander';
import { Command as CommanderProgram } from 'commander';
import { registerGmailAuthCommand } from './gmail-auth.js';
import { registerGcalAuthCommand } from './gcal-auth.js';
import { registerGdocsAuthCommand } from './gdocs-auth.js';
import { registerGdriveAuthCommand } from './gdrive-auth.js';
import { registerGtasksAuthCommand } from './gtasks-auth.js';

const GOOGLE_AUTH_SERVICES = ['gmail', 'gcal', 'gdocs', 'gdrive', 'gtasks'] as const;
type GoogleAuthService = (typeof GOOGLE_AUTH_SERVICES)[number];

function parseService(input: string): GoogleAuthService | null {
  const normalized = input.trim().toLowerCase();
  return GOOGLE_AUTH_SERVICES.find((service) => service === normalized) ?? null;
}

function registerGoogleServiceCommand(program: Command, service: GoogleAuthService): void {
  if (service === 'gmail') {
    registerGmailAuthCommand(program);
    return;
  }
  if (service === 'gcal') {
    registerGcalAuthCommand(program);
    return;
  }
  if (service === 'gdocs') {
    registerGdocsAuthCommand(program);
    return;
  }
  if (service === 'gdrive') {
    registerGdriveAuthCommand(program);
    return;
  }
  registerGtasksAuthCommand(program);
}

export function registerGoogleAuthCommand(program: Command): void {
  program
    .command('google-auth')
    .description('Authenticate Google services via OAuth2 (gmail, gcal, gdocs, gdrive, gtasks)')
    .requiredOption('-s, --service <service>', `Service: ${GOOGLE_AUTH_SERVICES.join('|')}`)
    .option('-c, --config <path>', 'Config file path')
    .option('--manual', 'Manually paste the authorization code instead of using a local server')
    .action(async (opts: { service: string; config?: string; manual?: boolean }) => {
      const service = parseService(opts.service);
      if (!service) {
        console.error(
          `Error: invalid --service "${opts.service}". Use one of: ${GOOGLE_AUTH_SERVICES.join(', ')}`,
        );
        process.exit(1);
      }

      const scopedProgram = new CommanderProgram();
      registerGoogleServiceCommand(scopedProgram, service);

      const args = ['node', 'flynn', `${service}-auth`];
      if (opts.config) {
        args.push('--config', opts.config);
      }
      if (opts.manual) {
        args.push('--manual');
      }
      await scopedProgram.parseAsync(args, { from: 'user' });
    });
}
