import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { Logger } from '@core/shared/application';
import type { UserAchievement } from '@core/identity';
import { InMemoryAchievementRepository } from './InMemoryAchievementRepository';

describe('InMemoryAchievementRepository (identity)', () => {
  let repository: InMemoryAchievementRepository;
  let logger: Logger;

  beforeEach(() => {
    logger = {
      debug: vi.fn(),
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    } as unknown as Logger;

    repository = new InMemoryAchievementRepository(logger);
  });

  it('seeds predefined achievements', async () => {
    const all = await repository.findAllAchievements();
    expect(all.length).toBeGreaterThan(0);

    const first = all[0]!;
    const found = await repository.findAchievementById(first.id);
    expect(found?.id).toBe(first.id);
  });

  it('creates and queries user achievements and stats', async () => {
    const all = await repository.findAllAchievements();
    const achievement = all[0]!;
    const userId = 'user-1';

    const ua: UserAchievement = {
      id: 'ua-1',
      userId,
      achievementId: achievement.id,
      isComplete: () => true,
    } as unknown as UserAchievement;

    await repository.createUserAchievement(ua);

    expect(await repository.hasUserEarnedAchievement(userId, achievement.id)).toBe(true);

    const leaderboard = await repository.getAchievementLeaderboard(10);
    expect(leaderboard.length).toBe(1);
    expect(leaderboard[0]?.userId).toBe(userId);
    expect(leaderboard[0]?.count).toBe(1);

    const stats = await repository.getUserAchievementStats(userId);
    expect(stats.total).toBe(1);
    expect(stats.points).toBeGreaterThan(0);
    expect(Object.values(stats.byCategory).reduce((a, b) => a + b, 0)).toBe(1);
  });
});
