import { beforeEach, describe, expect, it } from 'vitest';
import { Person } from '../../src/models/Person.js';
import { Player } from '../../src/models/Player.js';
import {
  handleLiveActivityEnded,
  handleLiveActivityToken,
} from '../../src/handlers/character.js';

class MockPlayerSession {
  player: Player;

  constructor(player: Player) {
    this.player = player;
  }
}

describe('Live Activity handlers', () => {
  let player: Player;
  let session: MockPlayerSession;

  beforeEach(() => {
    player = new Player({
      userId: 'user-live-1',
      status: 'playing',
      character: new Person({
        id: 'char-live-1',
        firstname: 'Alex',
        lastname: 'River',
      }),
    });
    session = new MockPlayerSession(player);
  });

  it('registers an ActivityKit push token for the active character', async () => {
    await handleLiveActivityToken({
      activityId: 'activity-1',
      token: 'activity-push-token',
      characterId: 'char-live-1',
    }, session as any);

    expect(player.liveActivity).toMatchObject({
      activityId: 'activity-1',
      pushToken: 'activity-push-token',
      characterId: 'char-live-1',
    });
    expect(player.liveActivity?.startedAt).toBeDefined();
  });

  it('ignores incomplete ActivityKit token payloads', async () => {
    await handleLiveActivityToken({
      activityId: 'activity-1',
      characterId: 'char-live-1',
    }, session as any);

    expect(player.liveActivity).toBeUndefined();
  });

  it('ignores ActivityKit tokens for stale characters', async () => {
    await handleLiveActivityToken({
      activityId: 'activity-1',
      token: 'activity-push-token',
      characterId: 'old-character',
    }, session as any);

    expect(player.liveActivity).toBeUndefined();
  });

  it('clears only the matching live activity registration', async () => {
    player.liveActivity = {
      activityId: 'activity-1',
      pushToken: 'activity-push-token',
      characterId: 'char-live-1',
      startedAt: '2026-05-26T14:00:00.000Z',
      lastSentAt: '2026-05-26T14:00:30.000Z',
    };

    await handleLiveActivityEnded({ activityId: 'other-activity' }, session as any);
    expect(player.liveActivity).toBeDefined();

    await handleLiveActivityEnded({ activityId: 'activity-1' }, session as any);
    expect(player.liveActivity).toBeUndefined();
  });
});
