// tests/helpers/socket-test-helpers.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved

import { vi } from "vitest";
import { Types } from "mongoose";
import {
  IUser,
  IDroneRegistration,
  IChatSession,
  IProject,
  DroneStatus,
  ChatSessionMode,
} from "@gadget/api";

import { nanoid } from "nanoid";

/**
 * Creates a mock socket object with common methods stubbed.
 */
export function createMockSocket(id?: string) {
  return {
    id: id || `socket-${nanoid()}`,
    on: vi.fn(),
    emit: vi.fn(),
    disconnect: vi.fn(),
    data: {},
    handshake: {
      auth: { token: "" },
    },
  };
}

/**
 * Creates a mock user object for testing.
 */
export function createMockUser(overrides?: Partial<IUser>): IUser {
  return {
    _id: nanoid(),
    email: `user-${nanoid()}@example.com`,
    displayName: "Test User",
    banned: false,
    admin: false,
    createdAt: new Date(),
    updatedAt: new Date(),
    ...overrides,
  } as IUser;
}

/**
 * Creates a mock drone registration for testing.
 */
export function createMockDroneRegistration(
  user?: IUser,
  overrides?: Partial<IDroneRegistration>,
): IDroneRegistration {
  const testUser = user || createMockUser();
  return {
    _id: nanoid(),
    createdAt: new Date(),
    updatedAt: new Date(),
    user: testUser,
    hostname: `drone-${nanoid()}`,
    workspaceDir: "/test/workspace",
    status: DroneStatus.Available,
    ...overrides,
  } as IDroneRegistration;
}

/**
 * Creates a mock chat session for testing.
 */
export function createMockChatSession(
  user?: IUser,
  project?: IProject,
  overrides?: Partial<IChatSession>,
): IChatSession {
  return {
    _id: nanoid(),
    createdAt: new Date(),
    updatedAt: new Date(),
    user: user?._id || nanoid(),
    project: project?._id || nanoid(),
    name: "Test Chat Session",
    mode: ChatSessionMode.Build,
    provider: nanoid(),
    selectedModel: "llama3.2",
    stats: {
      toolCallCount: 0,
      fileOpCount: 0,
      subagentCount: 0,
    },
    ...overrides,
  } as IChatSession;
}

/**
 * Creates a mock project for testing.
 */
export function createMockProject(
  user?: IUser,
  overrides?: Partial<IProject>,
): IProject {
  return {
    _id: nanoid(),
    createdAt: new Date(),
    updatedAt: new Date(),
    user: user?._id || nanoid(),
    slug: `project-${nanoid()}`,
    name: "Test Project",
    gitUrl: "https://github.com/test/test.git",
    ...overrides,
  } as IProject;
}

/**
 * Captures all emit calls for a mock socket.
 */
export interface EmitCall {
  event: string;
  args: any[];
}

export function captureSocketEmits(socket: any): EmitCall[] {
  const calls: EmitCall[] = [];
  socket.emit.mockImplementation((event: string, ...args: any[]) => {
    calls.push({ event, args });
  });
  return calls;
}

/**
 * Extracts callback from emit arguments for testing.
 */
export function extractCallback(emitCall: EmitCall): Function | null {
  const lastArg = emitCall.args[emitCall.args.length - 1];
  return typeof lastArg === "function" ? lastArg : null;
}
