import type { SlackMonitorContext } from "../context.js";

export type SlackSystemEventHandler = (args: {
  event: Record<string, unknown>;
  body: unknown;
}) => Promise<void>;

export type SlackSystemEventTestOverrides = {
  dmPolicy?: "open" | "pairing" | "allowlist" | "disabled";
  allowFrom?: string[];
  channelType?: "im" | "channel";
  channelUsers?: string[];
};

export function createSlackSystemEventTestHarness(overrides?: SlackSystemEventTestOverrides) {
  const handlers: Record<string, SlackSystemEventHandler> = {};
  const channelType = overrides?.channelType ?? "im";
  const app = {
    event: (name: string, handler: SlackSystemEventHandler) => {
      handlers[name] = handler;
    },
  };
  const ctx = {
    app,
    runtime: { error: () => {} },
    dmEnabled: true,
    dmPolicy: overrides?.dmPolicy ?? "open",
    defaultRequireMention: true,
    channelsConfig: overrides?.channelUsers
      ? {
          C1: {
            users: overrides.channelUsers,
            enabled: true,
          },
        }
      : undefined,
    groupPolicy: "open",
    allowFrom: overrides?.allowFrom ?? [],
    allowNameMatching: false,
    shouldDropMismatchedSlackEvent: () => false,
    isChannelAllowed: () => true,
    resolveChannelName: async () => ({
      name: channelType === "im" ? "direct" : "general",
      type: channelType,
    }),
    resolveUserName: async () => ({ name: "alice" }),
    resolveSlackSystemEventSessionKey: () => "agent:main:main",
  } as unknown as SlackMonitorContext;

  return {
    ctx,
    getHandler(name: string): SlackSystemEventHandler | null {
      return handlers[name] ?? null;
    },
  };
}
