/**
 * 已读回执管理器
 * 管理消息已读状态的同步和保护
 * 
 * 重构说明：
 * - 直接使用 zustand store 替代 IMessageStateManager
 * - 移除了 SubscriptionManager 调用，Zustand 的 set() 会自动触发组件重渲染
 */

import type { ConversationResponse } from '../../../types/dto';
import { messageService } from '@/services/message';
import { messageRepository, conversationRepository } from '@/database';
import type { ReadStateRecord, IReadReceiptManager } from '../types';
import { READ_STATE_PROTECTION_DELAY } from '../constants';
import { useMessageStore, normalizeConversationId } from '../store';

export class ReadReceiptManager implements IReadReceiptManager {
  /**
   * 正在进行中的已读 API 请求集合
   * 用于防止 fetchConversations 的服务器数据覆盖乐观已读状态
   */
  private pendingReadMap: Map<string, ReadStateRecord> = new Map();
  
  /**
   * 全局已读状态版本号，每次标记已读时递增
   */
  private readStateVersion: number = 0;

  /**
   * 标记会话已读
   * 关键方法：确保已读状态在所有组件间同步
   */
  async markAsRead(conversationId: string, seq: number): Promise<void> {
    const normalizedId = normalizeConversationId(conversationId);
    const store = useMessageStore.getState();
    const conversation = store.getConversation(normalizedId);
    
    if (!conversation) {
      console.warn('[ReadReceiptManager] 会话不存在:', normalizedId);
      return;
    }

    const prevUnreadCount = conversation.unread_count || 0;
    const existingRecord = this.pendingReadMap.get(normalizedId);

    // 使用 seq 去重：同一会话若已上报到更大/相同 seq，则跳过重复上报
    if (existingRecord && seq <= existingRecord.lastReadSeq) {
      return;
    }

    // 清除可能存在的旧定时器
    if (existingRecord?.clearTimer) {
      clearTimeout(existingRecord.clearTimer);
    }

    // 递增全局版本号
    this.readStateVersion++;
    const currentVersion = this.readStateVersion;

    // 1. 标记此会话有进行中的已读请求
    this.pendingReadMap.set(normalizedId, {
      timestamp: Date.now(),
      version: currentVersion,
      lastReadSeq: seq,
    });

    // 2. 乐观更新本地状态
    const updatedConv: ConversationResponse = {
      ...conversation,
      unread_count: 0,
      my_last_read_seq: Math.max(Number(conversation.my_last_read_seq || 0), seq),
    };
    
    store.updateConversation(updatedConv);
    
    const currentUnread = store.getUnreadCount();
    const newTotalUnread = Math.max(0, currentUnread.total - prevUnreadCount);
    store.setUnreadCount(newTotalUnread, currentUnread.system);

    // 3. 更新本地数据库
    messageRepository.markConversationAsRead(normalizedId).catch(console.error);

    // 4. 调用 API，完成后设置延迟清除保护
    try {
      await messageService.markAsRead(normalizedId, seq);
    } catch (error) {
      console.error('[ReadReceiptManager] 标记已读API失败:', error);
      
      // 失败时回滚状态
      store.updateConversation(conversation);
      store.setUnreadCount(currentUnread.total, currentUnread.system);
      
      // API 失败时立即清除保护
      this.pendingReadMap.delete(normalizedId);
      return;
    }

    // API 成功后，设置延迟清除保护
    const clearTimer = setTimeout(() => {
      const record = this.pendingReadMap.get(normalizedId);
      if (record && record.version === currentVersion) {
        this.pendingReadMap.delete(normalizedId);
      }
    }, READ_STATE_PROTECTION_DELAY);

    // 更新记录，保存定时器ID
    this.pendingReadMap.set(normalizedId, {
      timestamp: Date.now(),
      version: currentVersion,
      lastReadSeq: seq,
      clearTimer,
    });
  }

  /**
   * 标记所有消息已读
   */
  async markAllAsRead(): Promise<void> {
    const store = useMessageStore.getState();
    const conversations = store.conversations;
    const prevTotalUnread = store.getUnreadCount().total;
    const currentSystem = store.getUnreadCount().system;

    // 乐观更新
    conversations.forEach(conv => {
      conv.unread_count = 0;
    });
    
    store.setUnreadCount(0, currentSystem);

    try {
      // 标记系统消息已读
      await messageService.markAllSystemMessagesRead();

      // 标记所有会话已读
      const promises: Promise<any>[] = [];
      conversations.forEach(conv => {
        if ((conv.unread_count || 0) > 0) {
          promises.push(messageService.markAsRead(conv.id, conv.last_seq));
        }
      });

      await Promise.all(promises);
    } catch (error) {
      console.error('[ReadReceiptManager] 标记所有已读失败:', error);
      // 回滚
      store.setUnreadCount(prevTotalUnread, currentSystem);
    }
  }

  /**
   * 开始已读操作，返回版本号
   */
  beginReadOperation(conversationId: string, seq: number): number {
    this.readStateVersion++;
    const currentVersion = this.readStateVersion;
    
    this.pendingReadMap.set(conversationId, {
      timestamp: Date.now(),
      version: currentVersion,
      lastReadSeq: seq,
    });
    
    return currentVersion;
  }

  /**
   * 结束已读操作
   */
  endReadOperation(conversationId: string, version: number, success: boolean): void {
    if (!success) {
      this.pendingReadMap.delete(conversationId);
      return;
    }

    // API 成功后，设置延迟清除保护
    const clearTimer = setTimeout(() => {
      const record = this.pendingReadMap.get(conversationId);
      if (record && record.version === version) {
        this.pendingReadMap.delete(conversationId);
      }
    }, READ_STATE_PROTECTION_DELAY);

    const existingRecord = this.pendingReadMap.get(conversationId);
    if (existingRecord) {
      this.pendingReadMap.set(conversationId, {
        ...existingRecord,
        clearTimer,
      });
    }
  }

  /**
   * 检查是否有进行中的已读操作
   */
  isReadOperationPending(conversationId: string): boolean {
    return this.pendingReadMap.has(conversationId);
  }

  /**
   * 获取当前已读状态版本号
   */
  getReadStateVersion(): number {
    return this.readStateVersion;
  }

  /**
   * 获取待处理的已读映射
   */
  getPendingReadMap(): Map<string, ReadStateRecord> {
    return this.pendingReadMap;
  }

  /**
   * 根据已读保护状态智能合并会话
   */
  applyConversationFromFetch(conv: ConversationResponse): ConversationResponse {
    const id = normalizeConversationId(conv.id);
    const readRecord = this.pendingReadMap.get(id);
    
    let next: ConversationResponse;
    if (readRecord) {
      const shouldPreserveLocalRead = (conv.unread_count || 0) > 0;
      next = shouldPreserveLocalRead
        ? { ...conv, id, unread_count: 0 }
        : { ...conv, id };
    } else {
      next = { ...conv, id };
    }
    
    return this.normalizeConversationUnreadFromReadCursor(next);
  }

  /**
   * 当已读游标已追上 last_seq 时，强制未读为 0
   */
  normalizeConversationUnreadFromReadCursor(conv: ConversationResponse): ConversationResponse {
    const lastSeq = Number(conv.last_seq || 0);
    const myRead = Number(conv.my_last_read_seq ?? 0);
    if (lastSeq > 0 && myRead >= lastSeq && (conv.unread_count || 0) > 0) {
      return { ...conv, unread_count: 0 };
    }
    return conv;
  }

  /**
   * 重置所有状态
   */
  reset(): void {
    // 清除所有定时器
    for (const record of this.pendingReadMap.values()) {
      if (record.clearTimer) {
        clearTimeout(record.clearTimer);
      }
    }
    this.pendingReadMap.clear();
    this.readStateVersion = 0;
  }
}