import { OnlineSnapshot } from '../../../../src/domain/entities/online-snapshot.entity';
import { TimeWindow } from '../../../../src/domain/value-objects/time-window.vo';

describe('OnlineSnapshot Entity', () => {
  describe('create', () => {
    it('should create a new OnlineSnapshot with required properties', () => {
      const ts = new Date('2025-01-01T12:00:00.000Z');
      const snapshot = OnlineSnapshot.create({
        ts,
        onlineCount: 1000,
      });

      expect(snapshot.id).toBeNull();
      expect(snapshot.ts).toEqual(ts);
      expect(snapshot.onlineCount).toBe(1000);
      expect(snapshot.windowSeconds).toBe(TimeWindow.DEFAULT_ONLINE_WINDOW_SECONDS);
    });

    it('should create OnlineSnapshot with custom windowSeconds', () => {
      const ts = new Date('2025-01-01T12:00:00.000Z');
      const snapshot = OnlineSnapshot.create({
        ts,
        onlineCount: 500,
        windowSeconds: 300,
      });

      expect(snapshot.windowSeconds).toBe(300);
    });

    it('should create OnlineSnapshot with zero online count', () => {
      const ts = new Date();
      const snapshot = OnlineSnapshot.create({
        ts,
        onlineCount: 0,
      });

      expect(snapshot.onlineCount).toBe(0);
    });

    it('should create OnlineSnapshot with large online count', () => {
      const ts = new Date();
      const snapshot = OnlineSnapshot.create({
        ts,
        onlineCount: 1000000,
      });

      expect(snapshot.onlineCount).toBe(1000000);
    });
  });

  describe('reconstitute', () => {
    it('should reconstitute OnlineSnapshot from persistence data', () => {
      const id = BigInt(123);
      const ts = new Date('2025-01-01T12:00:00.000Z');
      const snapshot = OnlineSnapshot.reconstitute({
        id,
        ts,
        onlineCount: 2000,
        windowSeconds: 180,
      });

      expect(snapshot.id).toBe(id);
      expect(snapshot.ts).toEqual(ts);
      expect(snapshot.onlineCount).toBe(2000);
      expect(snapshot.windowSeconds).toBe(180);
    });

    it('should handle BigInt id correctly', () => {
      const largeId = BigInt('9007199254740993'); // > Number.MAX_SAFE_INTEGER
      const snapshot = OnlineSnapshot.reconstitute({
        id: largeId,
        ts: new Date(),
        onlineCount: 100,
        windowSeconds: 180,
      });

      expect(snapshot.id).toBe(largeId);
    });
  });

  describe('getters', () => {
    it('should return correct id', () => {
      const snapshot = OnlineSnapshot.reconstitute({
        id: BigInt(456),
        ts: new Date(),
        onlineCount: 100,
        windowSeconds: 180,
      });
      expect(snapshot.id).toBe(BigInt(456));
    });

    it('should return correct ts', () => {
      const ts = new Date('2025-06-15T10:30:00.000Z');
      const snapshot = OnlineSnapshot.create({
        ts,
        onlineCount: 100,
      });
      expect(snapshot.ts).toEqual(ts);
    });

    it('should return correct onlineCount', () => {
      const snapshot = OnlineSnapshot.create({
        ts: new Date(),
        onlineCount: 5000,
      });
      expect(snapshot.onlineCount).toBe(5000);
    });

    it('should return correct windowSeconds', () => {
      const snapshot = OnlineSnapshot.create({
        ts: new Date(),
        onlineCount: 100,
        windowSeconds: 600,
      });
      expect(snapshot.windowSeconds).toBe(600);
    });
  });
});
