import { projectToArchive } from '../../../../../src/modules/netaclaw/runtime/weixin_db/project_archive.js';
import type { MessageRow } from '../../../../../src/modules/netaclaw/runtime/weixin_db/message_repo.js';
import type { RoomInfo } from '../../../../../src/modules/netaclaw/runtime/weixin_db/room_resolver.js';

const room: RoomInfo = {
  tableName: 'Msg_abc',
  username: 'gA@chatroom',
  roomName: '产品研发群',
  isGroup: true,
};

describe('projectToArchive', () => {
  it('parses sender prefix for text message', () => {
    const row: MessageRow = {
      localId: 11,
      serverId: BigInt(999),
      localType: 1,
      realSenderId: BigInt(42),
      createTime: 1700000000,
      content: 'wxid_alice:\n你好',
      tableName: 'Msg_abc',
    };
    const a = projectToArchive(row, 6, room);
    expect(a.channelId).toBe(6);
    expect(a.roomId).toBe('gA@chatroom');
    expect(a.roomName).toBe('产品研发群');
    expect(a.msgTable).toBe('Msg_abc');
    expect(a.localId).toBe(11);
    expect(a.serverId).toBe('999');
    expect(a.localType).toBe(1);
    expect(a.senderWxid).toBe('wxid_alice');
    expect(a.createTime).toBe(1700000000);
    expect(a.content).toBe('你好');
    expect(a.rawHex).toBeNull();
  });

  it('enriches parsed sender wxid with contact identity', () => {
    const row: MessageRow = {
      localId: 13,
      serverId: BigInt(1000),
      localType: 1,
      realSenderId: BigInt(42),
      createTime: 1700002000,
      content: 'wxid_alice:\nhello',
      tableName: 'Msg_abc',
    };
    const a = projectToArchive(row, 6, room, username => {
      if (username !== 'wxid_alice') return undefined;
      return {
        username,
        remark: 'Alice备注',
        nickName: 'Alice昵称',
        displayName: 'Alice备注',
      };
    });
    expect(a.senderWxid).toBe('wxid_alice');
    expect(a.senderRemark).toBe('Alice备注');
    expect(a.senderNickName).toBe('Alice昵称');
    expect(a.senderDisplayName).toBe('Alice备注');
  });

  it('enriches no-prefix self sender from real sender id', () => {
    const row: MessageRow = {
      localId: 14,
      serverId: BigInt(1001),
      localType: 1,
      realSenderId: BigInt(2),
      createTime: 1700002001,
      content: 'hello from owner',
      tableName: 'Msg_abc',
    };
    const a = projectToArchive(
      row,
      6,
      room,
      undefined,
      (roomUsername, realSenderId) => {
        if (roomUsername !== 'gA@chatroom' || realSenderId !== '2') return undefined;
        return {
          username: 'shin_seed',
          remark: null,
          nickName: 'if',
          displayName: 'if',
        };
      },
    );
    expect(a.senderWxid).toBe('shin_seed');
    expect(a.senderNickName).toBe('if');
    expect(a.senderDisplayName).toBe('if');
  });

  it('keeps full XML content for non-text (no sender prefix)', () => {
    const xml = '<msg><img md5="abc"/></msg>';
    const row: MessageRow = {
      localId: 12, serverId: null, localType: 3, realSenderId: BigInt(7),
      createTime: 1700001000, content: xml, tableName: 'Msg_abc',
    };
    const a = projectToArchive(row, 6, room);
    expect(a.senderWxid).toBeNull();
    expect(a.content).toBe(xml);
    expect(a.localType).toBe(3);
  });

  it('serverId BigInt → string preserves precision', () => {
    const big = BigInt('9999999999999999');
    const row: MessageRow = {
      localId: 1, serverId: big, localType: 1, realSenderId: null,
      createTime: 1, content: 'x', tableName: 'Msg_abc',
    };
    const a = projectToArchive(row, 1, room);
    expect(a.serverId).toBe(big.toString());
  });

  it('rawHex null by default (content always set)', () => {
    const row: MessageRow = {
      localId: 1, serverId: null, localType: 1, realSenderId: null,
      createTime: 1, content: '', tableName: 'Msg_abc',
    };
    const a = projectToArchive(row, 1, room);
    expect(a.content).toBe('');
    expect(a.rawHex).toBeNull();
  });
});
