import { decryptDbToWorkDir } from './archive_decryptor.js';
import { MessageRepo, MessageRow } from './message_repo.js';
import { RoomResolver } from './room_resolver.js';
import { DbPaths } from './db_paths.js';

export interface IncrementalReaderConfig {
  dbPaths: DbPaths;
  messageDbKey: Buffer;
  sessionDbKey: Buffer;
  contactDbKey: Buffer;
  workDir: string;
  whitelistRoomNames: () => Set<string>;
}

export class IncrementalReader {
  private lastTsByTable = new Map<string, number>();
  private roomResolver = new RoomResolver();

  constructor(private readonly cfg: IncrementalReaderConfig) {}

  /** 一次性:
   *   1. 解 session.db → 加载 room map (username)
   *   2. 解 contact.db → merge display names (remark > nick_name > username)
   *   3. 解 message_0.db → baseline 每白名单表的 MAX(create_time)
   */
  async initialize(): Promise<void> {
    const sessionPlain = decryptDbToWorkDir({ srcDb: this.cfg.dbPaths.sessionDb, rawKey: this.cfg.sessionDbKey, workDir: this.cfg.workDir });
    this.roomResolver.loadFromSessionDb(sessionPlain);

    const contactPlain = decryptDbToWorkDir({ srcDb: this.cfg.dbPaths.contactDb, rawKey: this.cfg.contactDbKey, workDir: this.cfg.workDir });
    this.roomResolver.mergeContactNames(contactPlain);

    const msgPlain = decryptDbToWorkDir({ srcDb: this.cfg.dbPaths.messageDb, rawKey: this.cfg.messageDbKey, workDir: this.cfg.workDir });
    const repo = new MessageRepo(msgPlain);
    try {
      const allTables = repo.listMsgTables();
      const whitelist = this.cfg.whitelistRoomNames();
      const tables = this.roomResolver.filterWhitelistedGroupTables(allTables, whitelist);
      for (const t of tables) this.lastTsByTable.set(t, repo.maxCreateTime(t));
    } finally {
      repo.close();
    }
  }

  /**
   * WalWatcher 触发: 重解 message_0.db → 按当前白名单表 SELECT 新行。
   * 返回所有命中白名单的新消息行。
   */
  async readIncrement(): Promise<MessageRow[]> {
    const msgPlain = decryptDbToWorkDir({ srcDb: this.cfg.dbPaths.messageDb, rawKey: this.cfg.messageDbKey, workDir: this.cfg.workDir });
    const repo = new MessageRepo(msgPlain);
    const result: MessageRow[] = [];
    try {
      const allTables = repo.listMsgTables();
      const whitelist = this.cfg.whitelistRoomNames();
      const tables = this.roomResolver.filterWhitelistedGroupTables(allTables, whitelist);
      for (const t of tables) {
        const last = this.lastTsByTable.get(t) ?? 0;
        const rows = await repo.listSince(t, last);
        for (const row of rows) {
          result.push(row);
          if (row.createTime > last) this.lastTsByTable.set(t, row.createTime);
        }
      }
    } finally {
      repo.close();
    }
    return result;
  }

  /** 返回 tableName → roomName 映射,供上层 buildPseudoMessage 用。 */
  resolveRoom(tableName: string) {
    return this.roomResolver.lookup(tableName);
  }

  /** 暴露给同进程其他服务(如 archive_sync)调用 findRoomsByName / 其他 RoomResolver API。 */
  getRoomResolver(): RoomResolver {
    return this.roomResolver;
  }
}
