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

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

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

export interface SSEEvent {
  type: SSEEventType;
  payload: any;
  raw: any;
}

export type SSEEventHandler = (event: SSEEvent) => void;

export class SSEMessageHandler {
  private unsubscribeFns: Array<() => void> = [];
  private handlers: Set<SSEEventHandler> = new Set();

  connect(): void {
    if (this.unsubscribeFns.length > 0) return;

    // 监听私聊消息
    const unsubChat = sseService.on('chat', (message) => {
      this.emit('chat_message', this.parseChatMessage(message), message);
    });

    // 监听群聊消息
    const unsubGroupMessage = sseService.on('group_message', (message) => {
      this.emit('group_message', this.parseGroupMessage(message), message);
    });

    // 监听私聊已读回执
    const unsubRead = sseService.on('read', (message) => {
      this.emit('read_receipt', message, message);
    });

    // 监听群聊已读回执
    const unsubGroupRead = sseService.on('group_read', (message) => {
      this.emit('group_read_receipt', message, message);
    });

    // 监听私聊消息撤回
    const unsubRecall = sseService.on('recall', (message) => {
      this.emit('message_recalled', message, message);
    });

    // 监听群聊消息撤回
    const unsubGroupRecall = sseService.on('group_recall', (message) => {
      this.emit('group_message_recalled', message, message);
    });

    // 监听群聊输入状态
    const unsubGroupTyping = sseService.on('group_typing', (message) => {
      this.emit('typing', message, message);
    });

    // 监听群通知
    const unsubGroupNotice = sseService.on('group_notice', (message) => {
      this.emit('group_notice', this.parseGroupNotice(message), message);
    });

    this.unsubscribeFns = [
      unsubChat,
      unsubGroupMessage,
      unsubRead,
      unsubGroupRead,
      unsubRecall,
      unsubGroupRecall,
      unsubGroupTyping,
      unsubGroupNotice,
    ];
  }

  disconnect(): void {
    this.unsubscribeFns.forEach((fn) => fn());
    this.unsubscribeFns = [];
    this.handlers.clear();
  }

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

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

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

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

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

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

export const sseMessageHandler = new SSEMessageHandler();