/**
 * 已读回执管理器
 * 负责处理消息已读状态的同步
 */

import { messageService } from '../../services/messageService';
import { messageRepository } from '../../data/repositories/MessageRepository';
import type { MessageStateManager } from './MessageStateManager';

export interface ReadReceiptResult {
  conversationId: string;
  lastReadSeq: number;
  success: boolean;
}

export class ReadReceiptManager {
  private pendingOperations: Map<string, Promise<void>> = new Map();
  private stateManager: MessageStateManager | null = null;

  setStateManager(manager: MessageStateManager): void {
    this.stateManager = manager;
  }

  async markAsRead(
    conversationId: string,
    lastSeq: number
  ): Promise<ReadReceiptResult> {
    const existing = this.pendingOperations.get(conversationId);
    if (existing) {
      await existing;
    }

    if (!this.stateManager) {
      throw new Error('StateManager not set');
    }

    const version = this.stateManager.beginReadOperation(conversationId);

    const promise = this.executeMarkAsRead(conversationId, lastSeq, version);
    this.pendingOperations.set(conversationId, promise);

    try {
      await promise;
      return { conversationId, lastReadSeq: lastSeq, success: true };
    } catch (error) {
      console.error('[ReadReceiptManager] Failed to mark as read:', error);
      return { conversationId, lastReadSeq: lastSeq, success: false };
    } finally {
      this.pendingOperations.delete(conversationId);
      this.stateManager.endReadOperation(conversationId);
    }
  }

  private async executeMarkAsRead(
    conversationId: string,
    lastSeq: number,
    version: number
  ): Promise<void> {
    await messageService.markAsRead(conversationId, lastSeq);

    await messageRepository.markConversationAsRead(conversationId);

    if (this.stateManager) {
      this.stateManager.updateConversation(conversationId, {
        unreadCount: 0,
      });
    }
  }

  async markAllAsRead(): Promise<void> {
    if (!this.stateManager) return;

    const conversations = this.stateManager.getConversations();
    const unreadConversations = conversations.filter(c => c.unreadCount > 0);

    await Promise.all(
      unreadConversations.map(conv =>
        this.markAsRead(conv.id, conv.lastSeq)
      )
    );
  }

  isPending(conversationId: string): boolean {
    return this.pendingOperations.has(conversationId);
  }

  reset(): void {
    this.pendingOperations.clear();
  }
}

export const readReceiptManager = new ReadReceiptManager();