import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { afterEach, describe, expect, it, vi } from 'vitest';

describe('ConfigManager notification config shape', () => {
  let overrideRoot: string | null = null;

  afterEach(async () => {
    if (overrideRoot) {
      fs.rmSync(overrideRoot, { recursive: true, force: true });
      overrideRoot = null;
    }
    vi.resetModules();
    const pathDecoder = await import('../../../../src/main/utils/pathDecoder');
    pathDecoder.setClaudeBasePathOverride(null);
  });

  it('strips unknown notification keys while keeping autoResumeOnRateLimit', async () => {
    vi.resetModules();

    overrideRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'config-notifications-'));
    const configPath = path.join(overrideRoot, 'agent-teams-config.json');
    const pathDecoder = await import('../../../../src/main/utils/pathDecoder');
    pathDecoder.setClaudeBasePathOverride(overrideRoot);

    fs.writeFileSync(
      configPath,
      JSON.stringify({
        notifications: {
          notifyOnInboxMessages: true,
          autoResumeOnRateLimit: true,
          notifyOnTeamLaunched: false,
        },
      })
    );

    const { configManager } =
      await import('../../../../src/main/services/infrastructure/ConfigManager');
    const config = configManager.getConfig();

    expect(config.notifications.autoResumeOnRateLimit).toBe(true);
    expect(config.notifications.notifyOnTeamLaunched).toBe(false);
    expect('notifyOnInboxMessages' in config.notifications).toBe(false);

    await vi.waitFor(() => {
      const persisted = JSON.parse(fs.readFileSync(configPath, 'utf8')) as {
        notifications: Record<string, unknown>;
      };
      expect(persisted.notifications.autoResumeOnRateLimit).toBe(true);
      expect(persisted.notifications.notifyOnTeamLaunched).toBe(false);
      expect('notifyOnInboxMessages' in persisted.notifications).toBe(false);
    });
  });

  it('copies legacy config to the new Agent Teams config filename', async () => {
    vi.resetModules();

    overrideRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'config-notifications-'));
    const legacyConfigPath = path.join(overrideRoot, 'claude-devtools-config.json');
    const configPath = path.join(overrideRoot, 'agent-teams-config.json');
    const pathDecoder = await import('../../../../src/main/utils/pathDecoder');
    pathDecoder.setClaudeBasePathOverride(overrideRoot);

    fs.writeFileSync(
      legacyConfigPath,
      JSON.stringify({
        notifications: {
          autoResumeOnRateLimit: true,
        },
      })
    );

    const { configManager } =
      await import('../../../../src/main/services/infrastructure/ConfigManager');

    expect(configManager.getConfigPath()).toBe(configPath);
    expect(configManager.getConfig().notifications.autoResumeOnRateLimit).toBe(true);
    expect(fs.existsSync(legacyConfigPath)).toBe(true);
    expect(fs.existsSync(configPath)).toBe(true);

    await vi.waitFor(() => {
      const persisted = JSON.parse(fs.readFileSync(configPath, 'utf8')) as {
        notifications: Record<string, unknown>;
      };
      expect(persisted.notifications.autoResumeOnRateLimit).toBe(true);
      expect(persisted.notifications.enabled).toBe(true);
    });
  });

  it('does not overwrite an existing Agent Teams config with legacy config', async () => {
    vi.resetModules();

    overrideRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'config-notifications-'));
    const legacyConfigPath = path.join(overrideRoot, 'claude-devtools-config.json');
    const configPath = path.join(overrideRoot, 'agent-teams-config.json');
    const pathDecoder = await import('../../../../src/main/utils/pathDecoder');
    pathDecoder.setClaudeBasePathOverride(overrideRoot);

    fs.writeFileSync(
      legacyConfigPath,
      JSON.stringify({
        notifications: {
          autoResumeOnRateLimit: true,
        },
      })
    );
    fs.writeFileSync(
      configPath,
      JSON.stringify({
        notifications: {
          autoResumeOnRateLimit: false,
        },
      })
    );

    const { configManager } =
      await import('../../../../src/main/services/infrastructure/ConfigManager');

    expect(configManager.getConfigPath()).toBe(configPath);
    expect(configManager.getConfig().notifications.autoResumeOnRateLimit).toBe(false);

    await vi.waitFor(() => {
      const persisted = JSON.parse(fs.readFileSync(configPath, 'utf8')) as {
        notifications: Record<string, unknown>;
      };
      expect(persisted.notifications.autoResumeOnRateLimit).toBe(false);
      expect(persisted.notifications.enabled).toBe(true);
    });
  });

  it('copies pre-devtools legacy config when newer legacy config is absent', async () => {
    vi.resetModules();

    overrideRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'config-notifications-'));
    const legacyConfigPath = path.join(overrideRoot, 'claude-code-context-config.json');
    const configPath = path.join(overrideRoot, 'agent-teams-config.json');
    const pathDecoder = await import('../../../../src/main/utils/pathDecoder');
    pathDecoder.setClaudeBasePathOverride(overrideRoot);

    fs.writeFileSync(
      legacyConfigPath,
      JSON.stringify({
        notifications: {
          autoResumeOnRateLimit: true,
        },
      })
    );

    const { configManager } =
      await import('../../../../src/main/services/infrastructure/ConfigManager');

    expect(configManager.getConfigPath()).toBe(configPath);
    expect(configManager.getConfig().notifications.autoResumeOnRateLimit).toBe(true);
    expect(fs.existsSync(legacyConfigPath)).toBe(true);
    expect(fs.existsSync(configPath)).toBe(true);

    await vi.waitFor(() => {
      const persisted = JSON.parse(fs.readFileSync(configPath, 'utf8')) as {
        notifications: Record<string, unknown>;
      };
      expect(persisted.notifications.autoResumeOnRateLimit).toBe(true);
      expect(persisted.notifications.enabled).toBe(true);
    });
  });

  it('prefers a valid older legacy config over an invalid newer legacy config', async () => {
    vi.resetModules();

    overrideRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'config-notifications-'));
    const invalidNewerLegacyPath = path.join(overrideRoot, 'claude-devtools-config.json');
    const validOlderLegacyPath = path.join(overrideRoot, 'claude-code-context-config.json');
    const configPath = path.join(overrideRoot, 'agent-teams-config.json');
    const pathDecoder = await import('../../../../src/main/utils/pathDecoder');
    pathDecoder.setClaudeBasePathOverride(overrideRoot);

    fs.writeFileSync(invalidNewerLegacyPath, '', 'utf8');
    fs.writeFileSync(
      validOlderLegacyPath,
      JSON.stringify({
        notifications: {
          autoResumeOnRateLimit: true,
        },
      })
    );

    const { configManager } =
      await import('../../../../src/main/services/infrastructure/ConfigManager');

    expect(configManager.getConfigPath()).toBe(configPath);
    expect(configManager.getConfig().notifications.autoResumeOnRateLimit).toBe(true);

    await vi.waitFor(() => {
      const persisted = JSON.parse(fs.readFileSync(configPath, 'utf8')) as {
        notifications: Record<string, unknown>;
      };
      expect(persisted.notifications.autoResumeOnRateLimit).toBe(true);
      expect(persisted.notifications.enabled).toBe(true);
    });
    expect(fs.existsSync(validOlderLegacyPath)).toBe(true);
  });
});
