import { expect,test } from 'bun:test'; import { mkdtempSync } from 'node:fs'; import { join } from 'node:path'; import { openStore } from './store.js';
import type { Message } from './store.js';

const tmp=()=>join(mkdtempSync(join(process.env.TMPDIR??'/var/tmp','botmaster-store-')),'messages.db');

test('mints crockford ids',()=>{const s=openStore(tmp()),id=s.mintId();expect(id).toMatch(/^[0-9abcdefghjkmnpqrstvwxyz]{5}$/);s.close()});

// Regression: the INSERT once carried 15 placeholders against a 14-column table, and the
// retry loop reported every failure as "could not mint a unique message id".
test('inserts and reads back a message',()=>{
  const s=openStore(tmp());
  const m:Message={id:s.mintId(),direction:'out',sessionId:'sess-1',ticketId:null,channel:'overdeck',chatId:-1,priority:'fyi',parentId:null,text:'hello',createdAt:1,attempts:0,deliveredAt:null,escalatedAt:null,tgMessageId:null};
  s.insertMessage(m);
  const got=s.getMessage(m.id);
  expect(got?.text).toBe('hello');
  expect(got?.sessionId).toBe('sess-1');
  s.close();
});

test('a non-collision insert error surfaces verbatim',()=>{
  const s=openStore(tmp());
  const bad={id:'aaaaa',direction:'out'} as unknown as Message;
  expect(()=>s.insertMessage(bad)).not.toThrow(/unique message id/);
  s.close();
});

test('records attachments in upload order',()=>{const s=openStore(tmp());s.recordAttachment('message-1',2,'second.txt',20,202);s.recordAttachment('message-1',1,'first.txt',10,201);expect(s.listAttachments('message-1')).toEqual([{messageId:'message-1',seq:1,path:'first.txt',bytes:10,tgMessageId:201},{messageId:'message-1',seq:2,path:'second.txt',bytes:20,tgMessageId:202}]);s.close()});

test('main claim is a singleton that the latest claimant overwrites',()=>{
  const s=openStore(tmp());
  expect(s.getMainClaim()).toBeNull();
  s.claimMain('session-a',100);
  expect(s.getMainClaim()).toEqual({sessionId:'session-a',claimedAt:100});
  s.claimMain('session-b',200);
  expect(s.getMainClaim()).toEqual({sessionId:'session-b',claimedAt:200});
  s.close();
});

test('an escalated inbound row is not stale undelivered',()=>{
  const s=openStore(tmp());
  const m:Message={id:s.mintId(),direction:'in',sessionId:'sess-1',ticketId:null,channel:'overdeck',chatId:-1,priority:'needs-answer',parentId:null,text:'hello',createdAt:1,attempts:3,deliveredAt:null,escalatedAt:null,tgMessageId:null};
  s.insertMessage(m);s.markEscalated(m.id,2);
  expect(s.staleUndelivered(3)).toEqual([]);
  expect(s.getMessage(m.id)?.deliveredAt).toBeNull();
  s.close();
});
