import { describe, expect, it, vi } from 'vitest';

const { post, get } = vi.hoisted(() => ({ post: vi.fn(), get: vi.fn() }));
vi.mock('./api', () => ({ default: { post, get } }));

import { vibeService } from './vibeService';

describe('durable vibe service', () => {
  it('serves the next item with the caller plan version', async () => {
    post.mockResolvedValue({ data: { sessionId: 'session', planVersion: 3, now: null, preview: [] } });

    await vibeService.next('session', 3);

    expect(post).toHaveBeenCalledWith('/v2/vibe/sessions/session/advance', { expectedPlanVersion: 3 });
  });

  it('uses an explicit idempotency key to advance a served but unplayable item', async () => {
    post.mockResolvedValue({ data: { sessionId: 'session', planVersion: 3, now: null, preview: [] } });

    await vibeService.advancePastUnplayable('session', 3, {
      eventId: 'event', planVersionId: 'plan', ordinal: 4, trackId: 'track',
    });

    expect(post).toHaveBeenCalledWith('/v2/vibe/sessions/session/advance', {
      expectedPlanVersion: 3,
      unplayable: { eventId: 'event', planVersionId: 'plan', ordinal: 4, trackId: 'track' },
    });
  });

  it('sends client event ids to the durable event ledger', async () => {
    post.mockResolvedValue({ data: { sessionId: 'session', planVersion: 2, now: null, preview: [] } });

    await vibeService.event('session', {
      eventId: 'event', type: 'progress', occurredAt: '2026-01-01T00:00:00.000Z', trackId: 'track', positionMs: 30000,
    });

    expect(post).toHaveBeenCalledWith('/v2/vibe/sessions/session/events', expect.objectContaining({
      eventId: 'event', type: 'progress', trackId: 'track', positionMs: 30000,
    }));
  });
});
