import { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';

export interface SocketCompat {
  on(event: string, callback: (...args: any[]) => void): void;
  off(event: string, callback?: (...args: any[]) => void): void;
  emit(event: string, ...args: any[]): void;
  disconnect(): void;
  status: string;
}

let connection: HubConnection | null = null;
let socketWrapper: SocketCompat | null = null;

export function connectSocket(token: string): SocketCompat {
  if (connection && (connection.state === 'Connected' || connection.state === 'Connecting')) {
    return socketWrapper!;
  }

  connection = new HubConnectionBuilder()
    .withUrl('/hubs/chat', {
      accessTokenFactory: () => token
    })
    .withAutomaticReconnect()
    .configureLogging(LogLevel.Error)
    .build();

  // Обертка для совместимости с Socket.io API
  socketWrapper = {
    on: (event: string, callback: (...args: any[]) => void) => {
      // console.log(`[SignalR] Registering handler for: ${event}`);
      connection?.on(event, callback);
    },
    off: (event: string, callback?: (...args: any[]) => void) => {
      if (callback) {
        connection?.off(event, callback);
      } else {
        connection?.off(event);
      }
    },
    emit: (event: string, ...args: any[]) => {
      const state = connection?.state;
      // console.log(`[SignalR] emit('${event}') called, connection state: ${state}`);
      if (connection?.state === 'Connected') {
        // В SignalR invoke возвращает Promise, но Socket.io emit - нет.
        // Мы просто запускаем и логируем ошибки.
        connection.invoke(event, ...args)
          // .then(() => console.log(`[SignalR] invoke('${event}') completed successfully`))
          .catch(err => console.error(`SignalR emit error (${event}):`, err));
      } else {
        // console.warn(`SignalR emit skipped (${event}): connection state is ${state}`);
      }
    },
    disconnect: () => {
      connection?.stop();
    },
    get status() {
      return connection?.state || 'Disconnected';
    }
  };

  connection.start()
    .then(() => {
    })
    .catch(err => console.error('[SignalR] Connection error:', err.toString()));

  connection.onclose((error) => {
  });

  connection.onreconnecting((error) => {
  });

  connection.onreconnected((connectionId) => {
  });

  return socketWrapper;
}

export function getSocket(): SocketCompat | null {
  return socketWrapper;
}

export function disconnectSocket() {
  if (connection) {
    connection.stop();
    connection = null;
    socketWrapper = null;
  }
}
