/**
 * Unit tests for settings.ts pure functions.
 * Tests migrateToGroupedFormat which converts legacy flat settings to grouped format.
 */

import { expect, test, describe } from "bun:test";
import { migrateToGroupedFormat } from "../src/core/settings.ts";

// =============================================================================
// migrateToGroupedFormat
// =============================================================================

describe("migrateToGroupedFormat", () => {
  test("migrates legacy auto_invite fields to grouped format", () => {
    const legacy = {
      name: "my-workspace",
      auto_invite_enabled: true,
      auto_invite_as: "operator",
      auto_invite_mode: "add",
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.auto_invite).toEqual({
      enabled: true,
      operator: true,
      mode: "add",
    });
  });

  test("migrates legacy auto_invite with non-operator role", () => {
    const legacy = {
      name: "ws",
      auto_invite_enabled: true,
      auto_invite_as: "developer",
      auto_invite_mode: "invite",
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.auto_invite).toEqual({
      enabled: true,
      operator: false,
      mode: "invite",
    });
  });

  test("migrates legacy auto_invite when disabled", () => {
    const legacy = {
      name: "ws",
      auto_invite_enabled: false,
      auto_invite_as: "operator",
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.auto_invite!.enabled).toBe(false);
  });

  test("preserves already-grouped auto_invite", () => {
    const grouped = {
      name: "ws",
      auto_invite: { enabled: true, operator: false, mode: "invite" as const },
    };
    const result = migrateToGroupedFormat(grouped);
    expect(result.auto_invite).toEqual({
      enabled: true,
      operator: false,
      mode: "invite",
    });
  });

  test("migrates legacy error_handler string to grouped format", () => {
    const legacy = {
      name: "ws",
      error_handler: "u/admin/error_handler",
      error_handler_extra_args: { notify: true },
      error_handler_muted_on_cancel: true,
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.error_handler).toEqual({
      path: "u/admin/error_handler",
      extra_args: { notify: true },
      muted_on_cancel: true,
    });
  });

  test("preserves already-grouped error_handler", () => {
    const grouped = {
      name: "ws",
      error_handler: {
        path: "u/admin/handler",
        extra_args: {},
        muted_on_cancel: false,
      },
    };
    const result = migrateToGroupedFormat(grouped);
    expect(result.error_handler).toEqual({
      path: "u/admin/handler",
      extra_args: {},
      muted_on_cancel: false,
    });
  });

  test("migrates legacy success_handler string to grouped format", () => {
    const legacy = {
      name: "ws",
      success_handler: "u/admin/on_success",
      success_handler_extra_args: { channel: "#deploys" },
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.success_handler).toEqual({
      path: "u/admin/on_success",
      extra_args: { channel: "#deploys" },
    });
  });

  test("preserves already-grouped success_handler", () => {
    const grouped = {
      name: "ws",
      success_handler: { path: "u/admin/handler", extra_args: {} },
    };
    const result = migrateToGroupedFormat(grouped);
    expect(result.success_handler).toEqual({
      path: "u/admin/handler",
      extra_args: {},
    });
  });

  test("copies non-legacy fields through", () => {
    const settings = {
      name: "my-workspace",
      webhook: "https://example.com/hook",
      deploy_to: "staging",
      default_app: "u/admin/dashboard",
      mute_critical_alerts: true,
      color: "#ff0000",
    };
    const result = migrateToGroupedFormat(settings);
    expect(result.name).toBe("my-workspace");
    expect(result.webhook).toBe("https://example.com/hook");
    expect(result.deploy_to).toBe("staging");
    expect(result.default_app).toBe("u/admin/dashboard");
    expect(result.mute_critical_alerts).toBe(true);
    expect(result.color).toBe("#ff0000");
  });

  test("handles minimal settings with only name", () => {
    const result = migrateToGroupedFormat({ name: "ws" });
    expect(result.name).toBe("ws");
    expect(result.auto_invite).toBeUndefined();
    expect(result.error_handler).toBeUndefined();
    expect(result.success_handler).toBeUndefined();
  });

  test("defaults name to empty string when missing", () => {
    const result = migrateToGroupedFormat({});
    expect(result.name).toBe("");
  });

  test("defaults auto_invite_mode to invite when missing", () => {
    const legacy = {
      name: "ws",
      auto_invite_enabled: true,
      auto_invite_as: "operator",
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.auto_invite!.mode).toBe("invite");
  });

  test("defaults error_handler_muted_on_cancel to false when missing", () => {
    const legacy = {
      name: "ws",
      error_handler: "u/admin/handler",
    };
    const result = migrateToGroupedFormat(legacy);
    expect(result.error_handler!.muted_on_cancel).toBe(false);
  });

  test("preserves ai_config, large_file_storage, git_sync, default_scripts, operator_settings", () => {
    const settings = {
      name: "ws",
      ai_config: { provider: "openai" },
      large_file_storage: { type: "s3" },
      git_sync: { enabled: true },
      default_scripts: { python: "template.py" },
      operator_settings: { hideCode: true },
    };
    const result = migrateToGroupedFormat(settings);
    expect(result.ai_config).toEqual({ provider: "openai" });
    expect(result.large_file_storage).toEqual({ type: "s3" });
    expect(result.git_sync).toEqual({ enabled: true });
    expect(result.default_scripts).toEqual({ python: "template.py" });
    expect(result.operator_settings).toEqual({ hideCode: true });
  });

  test("does not include undefined fields in result", () => {
    const result = migrateToGroupedFormat({ name: "ws" });
    expect("webhook" in result).toBe(false);
    expect("deploy_to" in result).toBe(false);
    expect("color" in result).toBe(false);
    expect("slack_team_id" in result).toBe(false);
    expect("slack_name" in result).toBe(false);
    expect("slack_command_script" in result).toBe(false);
  });

  test("copies slack fields through", () => {
    const settings = {
      name: "ws",
      slack_team_id: "T12345",
      slack_name: "my-team",
      slack_command_script: "u/admin/slack_handler",
    };
    const result = migrateToGroupedFormat(settings);
    expect(result.slack_team_id).toBe("T12345");
    expect(result.slack_name).toBe("my-team");
    expect(result.slack_command_script).toBe("u/admin/slack_handler");
  });
});
