/**
 * Shared WebSocket envelope → handler payload extraction.
 * Must stay in sync with WebSocketServer message routing.
 */

export interface WebSocketEnvelope {
  type: string;
  message?: unknown;
  userID?: string;
  [key: string]: unknown;
}

export interface ExtractedCommand {
  commandType: string;
  payload: unknown;
}

const DIRECT_COMMANDS = ['stop', 'start', 'restart'] as const;

function isNestedCommandEnvelope(
  message: unknown
): message is { type: string; message?: unknown } {
  return (
    !!message &&
    typeof message === 'object' &&
    'type' in message &&
    typeof (message as { type?: unknown }).type === 'string'
  );
}

/**
 * Derive the command type and handler payload from a raw client envelope.
 */
export function extractPayload(envelope: WebSocketEnvelope): ExtractedCommand {
  let commandType = envelope.type;
  let payload: unknown = envelope;

  if (
    envelope.type === 'command' &&
    envelope.message &&
    isNestedCommandEnvelope(envelope.message)
  ) {
    const nestedMessage = envelope.message;
    commandType = nestedMessage.type;
    payload = nestedMessage.message ?? nestedMessage;
  } else if (
    typeof envelope.message === 'string' &&
    DIRECT_COMMANDS.includes(envelope.message as (typeof DIRECT_COMMANDS)[number])
  ) {
    commandType = envelope.message;
    payload = envelope;
  } else if (envelope.message !== undefined) {
    payload = envelope.message;
  }

  return { commandType, payload };
}
