import type { PagerStatus } from '../interface/pager';

/**
 * Socket connection configuration for admin pager module
 * Used by frontend to establish WebSocket connection
 */
export interface PagerSocketConnectionConfig {
  /**
   * WebSocket server URL
   * Example: 'http://localhost:3000' or 'https://api.example.com'
   */
  serverUrl: string;

  /**
   * Socket namespace (default: '/pager')
   * The gateway is configured to use '/pager' namespace
   */
  namespace?: string;

  /**
   * JWT authentication token for admin
   * Token should contain adminId and restId in payload
   * Can be passed via auth.token, auth.authorization, query.token, or headers.authorization
   * Example: { auth: { token: 'your-jwt-token' } }
   */
  token: string;

  /**
   * Optional: Additional connection options
   */
  options?: {
    /**
     * Enable auto-reconnection
     * @default true
     */
    autoConnect?: boolean;

    /**
     * Connection timeout in milliseconds
     * @default 5000
     */
    timeout?: number;

    /**
     * Enable transports (websocket, polling)
     * @default ['websocket', 'polling']
     */
    transports?: ('websocket' | 'polling')[];
  };
}

/**
 * Socket event names for pager module
 */
export enum PagerSocketEvents {
  // Client to Server Events
  JOIN_RESTAURANT = 'join:restaurant',
  LEAVE_ROOM = 'leave:room',
  GET_PAGERS = 'get:pagers',
  UPDATE_PAGER_STATUS = 'update:pager:status',

  // Server to Client Events
  JOINED = 'joined',
  LEFT = 'left',
  PAGER_CREATED = 'pager:created',
  PAGER_STATUS_UPDATED = 'pager:status:updated',
  PAGERS_LIST = 'pagers:list',
  PAGER_STATUS_UPDATED_RESPONSE = 'pager:status:updated:response',
  ERROR = 'error',
  CONNECT = 'connect',
  DISCONNECT = 'disconnect',
}

/**
 * Payload for joining restaurant room
 * Note: restId is automatically extracted from JWT token, no need to send it
 */
export type JoinRestaurantPayload = Record<string, never>;

/**
 * Payload for leaving a room
 */
export interface LeaveRoomPayload {
  room: string;
}

/**
 * Payload for getting pagers list
 * Note: restId is automatically extracted from JWT token, no need to send it
 */
export type GetPagersPayload = Record<string, never>;

/**
 * Payload for updating pager status
 * Note: restId and adminId are automatically extracted from JWT token
 */
export interface UpdatePagerStatusPayload {
  pagerId: string;
  status: PagerStatus;
}

/**
 * Response when successfully joined a room
 */
export interface JoinedResponse {
  room: string;
  message: string;
}

/**
 * Response when successfully left a room
 */
export interface LeftResponse {
  room: string;
  message: string;
}

/**
 * User information in pager response
 */
export interface PagerUserInfo {
  id: string;
  firstName: string;
  lastName?: string;
}

/**
 * Staff information in pager response
 */
export interface PagerStaffInfo {
  id: string;
  firstName: string;
  lastName?: string;
}

/**
 * Pager data structure emitted by socket events
 */
export interface PagerSocketData {
  id: string;
  tableNumber: string;
  message?: string;
  status: PagerStatus;
  cookieId?: string;
  createdAt?: Date | string;
  updatedAt?: Date | string;
  user?: PagerUserInfo | null;
  staff?: PagerStaffInfo | null;
}

/**
 * Payload for pager:created event
 */
export interface PagerCreatedPayload {
  pager: PagerSocketData;
}

/**
 * Payload for pager:status:updated event
 */
export interface PagerStatusUpdatedPayload {
  pager: PagerSocketData;
}

/**
 * Payload for pagers:list event
 */
export interface PagersListPayload {
  pagers: PagerSocketData[];
}

/**
 * Payload for pager:status:updated:response event (response to update request)
 */
export interface PagerStatusUpdatedResponsePayload {
  pager: PagerSocketData;
}

/**
 * Error response from socket
 */
export interface SocketErrorResponse {
  message: string;
  code?: string;
  details?: unknown;
}

/**
 * Complete socket event map for type safety
 */
export interface PagerSocketEventMap {
  // Client emits
  [PagerSocketEvents.JOIN_RESTAURANT]: (payload?: JoinRestaurantPayload) => void;
  [PagerSocketEvents.LEAVE_ROOM]: (payload: LeaveRoomPayload) => void;
  [PagerSocketEvents.GET_PAGERS]: (payload?: GetPagersPayload) => void;
  [PagerSocketEvents.UPDATE_PAGER_STATUS]: (payload: UpdatePagerStatusPayload) => void;

  // Server emits
  [PagerSocketEvents.JOINED]: (response: JoinedResponse) => void;
  [PagerSocketEvents.LEFT]: (response: LeftResponse) => void;
  [PagerSocketEvents.PAGER_CREATED]: (payload: PagerCreatedPayload) => void;
  [PagerSocketEvents.PAGER_STATUS_UPDATED]: (payload: PagerStatusUpdatedPayload) => void;
  [PagerSocketEvents.PAGERS_LIST]: (payload: PagersListPayload) => void;
  [PagerSocketEvents.PAGER_STATUS_UPDATED_RESPONSE]: (payload: PagerStatusUpdatedResponsePayload) => void;
  [PagerSocketEvents.ERROR]: (error: SocketErrorResponse) => void;
  [PagerSocketEvents.CONNECT]: () => void;
  [PagerSocketEvents.DISCONNECT]: (reason: string) => void;
}
