/**
 * WebSocket 消息处理器
 * 只负责处理 WebSocket 消息，不管理状态
 */

import { sseService, WSChatMessage, WSGroupChatMessage, WSReadMessage, WSGroupReadMessage, WSRecallMessage, WSGroupRecallMessage, WSGroupTypingMessage, WSGroupNoticeMessage, GroupNoticeType } from '../../services/sseService';
import type { Message, GroupNotice } from '../../core/entities/Message';

export type WebSocketEventType =
  | 'chat_message'
  | 'group_message'
  | 'read_receipt'
  | 'group_read_receipt'
  | 'message_recalled'
  | 'group_message_recalled'
  | 'typing'
  | 'group_notice';

export interface WebSocketEvent {
  type: WebSocketEventType;
  payload: any;
  raw: any;
}

export type WebSocketEventHandler = (event: WebSocketEvent) => void;

export class WebSocketMessageHandler {
  private unsubscribe: (() => void) | null = null;
  private handlers: Set<WebSocketEventHandler> = new Set();

  connect(): void {
    if (this.unsubscribe) return;

    this.unsubscribe = sseService.subscribe(this.handleSSEEvent.bind(this));
  }

  disconnect(): void {
    if (this.unsubscribe) {
      this.unsubscribe();
      this.unsubscribe = null;
    }
    this.handlers.clear();
  }

  subscribe(handler: WebSocketEventHandler): () => void {
    this.handlers.add(handler);
    return () => this.handlers.delete(handler);
  }

  private handleSSEEvent(event: any): void {
    const { type, data } = event;

    switch (type) {
      case 'chat':
        this.emit('chat_message', this.parseChatMessage(data), data);
        break;
      case 'group_message':
        this.emit('group_message', this.parseGroupMessage(data), data);
        break;
      case 'read':
        this.emit('read_receipt', data, data);
        break;
      case 'group_read':
        this.emit('group_read_receipt', data, data);
        break;
      case 'recall':
        this.emit('message_recalled', data, data);
        break;
      case 'group_recall':
        this.emit('group_message_recalled', data, data);
        break;
      case 'typing':
        this.emit('typing', data, data);
        break;
      case 'group_notice':
        this.emit('group_notice', this.parseGroupNotice(data), data);
        break;
      default:
        console.log('[WebSocketMessageHandler] Unknown event type:', type);
    }
  }

  private emit(type: WebSocketEventType, payload: any, raw: any): void {
    const event: WebSocketEvent = { type, payload, raw };
    this.handlers.forEach(handler => {
      try {
        handler(event);
      } catch (error) {
        console.error('[WebSocketMessageHandler] Handler error:', error);
      }
    });
  }

  private parseChatMessage(data: WSChatMessage): Message {
    return {
      id: data.id || '',
      conversationId: data.conversationId || data.conversation_id || '',
      senderId: data.senderId || data.sender_id || '',
      seq: data.seq || 0,
      segments: data.segments || [],
      createdAt: data.createdAt || data.created_at || new Date().toISOString(),
      status: 'normal',
      sender: data.sender,
    };
  }

  private parseGroupMessage(data: WSGroupChatMessage): Message {
    return {
      id: data.id || '',
      conversationId: data.groupId || data.group_id || '',
      senderId: data.senderId || data.sender_id || '',
      seq: data.seq || 0,
      segments: data.segments || [],
      createdAt: data.createdAt || data.created_at || new Date().toISOString(),
      status: 'normal',
      sender: data.sender,
    };
  }

  private parseGroupNotice(data: WSGroupNoticeMessage): GroupNotice {
    return {
      type: data.noticeType || data.notice_type || 'member_join',
      groupId: data.groupId || data.group_id || '',
      data: data.data || {},
      timestamp: data.timestamp || Date.now(),
      messageId: data.messageId || data.message_id,
      seq: data.seq,
    };
  }

  isConnected(): boolean {
    return sseService.isConnected();
  }
}

export const webSocketMessageHandler = new WebSocketMessageHandler();