import { describe, it, expect } from 'vitest';
import { setupAutomation } from './automation.js';
import { ConfigBuilder } from './config.js';
import type { Prompter } from './prompts.js';

function makePrompter(answers: {
  confirms?: boolean[];
  asks?: string[];
}): Prompter {
  const confirms = [...(answers.confirms ?? [])];
  const asks = [...(answers.asks ?? [])];

  return {
    ask: async (_question: string, defaultValue?: string) => {
      if (asks.length > 0) {
        return asks.shift() ?? '';
      }
      return defaultValue ?? '';
    },
    confirm: async (_question: string, defaultYes?: boolean) => {
      if (confirms.length > 0) {
        return confirms.shift() ?? false;
      }
      return defaultYes ?? false;
    },
    choose: async <T = string>(_question: string, options: Array<{ value: T }>) => options[0].value,
    password: async () => '',
    println: () => {},
  };
}

describe('setupAutomation', () => {
  it('applies operator pack defaults when enabled', async () => {
    const builder = new ConfigBuilder();
    builder.setTelegram('123:ABC', [987654321]);

    const p = makePrompter({
      confirms: [
        true,  // enable operator pack
        true,  // include minio sync
        false, // enable cron scheduler
        false, // enable webhook receiver
        false, // configure google services
      ],
      asks: [
        'telegram', // output channel
        '987654321', // output peer
        '0 3 * * *', // backup schedule
        '0 7 * * 1-5', // daily briefing schedule
      ],
    });

    await setupAutomation(p, builder);

    const config = builder.build() as Record<string, unknown>;
    const backup = config.backup as Record<string, unknown>;
    const automation = config.automation as Record<string, unknown>;
    const heartbeat = automation.heartbeat as Record<string, unknown>;
    const briefing = automation.daily_briefing as Record<string, unknown>;
    const minioSync = automation.minio_sync as Record<string, unknown>;

    expect(backup.enabled).toBe(true);
    expect(backup.schedule).toBe('0 3 * * *');
    expect(heartbeat.enabled).toBe(true);
    expect(heartbeat.notify_cooldown).toBe('30m');
    expect((heartbeat.notify as Record<string, unknown>).channel).toBe('telegram');
    expect((heartbeat.notify as Record<string, unknown>).peer).toBe('987654321');
    expect(briefing.enabled).toBe(true);
    expect(briefing.schedule).toBe('0 7 * * 1-5');
    expect(minioSync.enabled).toBe(true);
  });

  it('allows overriding operator pack output routing', async () => {
    const builder = new ConfigBuilder();

    const p = makePrompter({
      confirms: [
        true,  // enable operator pack
        false, // include minio sync
        false, // enable cron scheduler
        false, // enable webhook receiver
        false, // configure google services
      ],
      asks: [
        'discord', // output channel
        'ops-room', // output peer
        '0 4 * * *', // backup schedule
        '0 9 * * *', // daily briefing schedule
      ],
    });

    await setupAutomation(p, builder);

    const config = builder.build() as Record<string, unknown>;
    const backup = config.backup as Record<string, unknown>;
    const automation = config.automation as Record<string, unknown>;
    const heartbeat = automation.heartbeat as Record<string, unknown>;
    const briefing = automation.daily_briefing as Record<string, unknown>;

    expect((backup.notify as Record<string, unknown>).channel).toBe('discord');
    expect((backup.notify as Record<string, unknown>).peer).toBe('ops-room');
    expect((heartbeat.notify as Record<string, unknown>).channel).toBe('discord');
    expect((briefing.output as Record<string, unknown>).peer).toBe('ops-room');
    expect(automation.minio_sync).toBeUndefined();
  });

  it('leaves operator pack disabled when not selected', async () => {
    const builder = new ConfigBuilder();

    const p = makePrompter({
      confirms: [
        false, // enable operator pack
        false, // enable cron scheduler
        false, // enable webhook receiver
        false, // configure google services
      ],
    });

    await setupAutomation(p, builder);

    const config = builder.build() as Record<string, unknown>;
    const backup = config.backup as Record<string, unknown> | undefined;
    const automation = config.automation as Record<string, unknown> | undefined;

    expect(backup).toBeUndefined();
    expect(automation?.daily_briefing).toBeUndefined();
    expect(automation?.heartbeat).toBeUndefined();
    expect(automation?.minio_sync).toBeUndefined();
  });

  it('skips operator-pack reconfiguration prompts when already configured and not reconfigured', async () => {
    const builder = new ConfigBuilder();
    builder.applyOperatorPack({
      outputChannel: 'telegram',
      outputPeer: '123',
      backupSchedule: '0 2 * * *',
      dailyBriefingSchedule: '0 8 * * *',
      enableMinioSync: true,
    });

    const p = makePrompter({
      confirms: [
        false, // reconfigure operator pack?
        false, // enable cron scheduler
        false, // enable webhook receiver
        false, // configure google services
      ],
    });

    await setupAutomation(p, builder);

    const config = builder.build() as Record<string, unknown>;
    const backup = config.backup as Record<string, unknown>;
    const automation = config.automation as Record<string, unknown>;
    const briefing = automation.daily_briefing as Record<string, unknown>;

    expect(backup.schedule).toBe('0 2 * * *');
    expect(briefing.schedule).toBe('0 8 * * *');
  });
});
