import type { AchievementRepository } from '@core/identity/domain/repositories/AchievementRepository';
import { Test, TestingModule } from '@nestjs/testing';
import { beforeEach, describe, expect, it, vi, afterEach } from 'vitest';
import { ACHIEVEMENT_REPOSITORY_TOKEN } from './AchievementPersistenceTokens';

describe('AchievementPersistenceModule', () => {
  const originalEnv = { ...process.env };

  beforeEach(() => {
    // Reset environment before each test
    delete process.env.GRIDPILOT_API_PERSISTENCE;
    // Clear module cache to ensure fresh imports
    vi.resetModules();
  });

  afterEach(() => {
    // Restore original environment
    process.env = { ...originalEnv };
  });

  it('uses inmemory providers when GRIDPILOT_API_PERSISTENCE=inmemory', async () => {
    process.env.GRIDPILOT_API_PERSISTENCE = 'inmemory';

    const { AchievementPersistenceModule } = await import('./AchievementPersistenceModule');

    const module: TestingModule = await Test.createTestingModule({
      imports: [AchievementPersistenceModule],
    }).compile();

    const repository = module.get<AchievementRepository>(ACHIEVEMENT_REPOSITORY_TOKEN);
    // The adapter should provide the domain interface methods
    expect(repository).toBeDefined();
    expect(typeof repository.createAchievement).toBe('function');
    expect(typeof repository.findAchievementById).toBe('function');
    expect(typeof repository.findAllAchievements).toBe('function');
  });

  it('uses postgres providers when GRIDPILOT_API_PERSISTENCE=postgres', async () => {
    const shouldRun = Boolean(process.env.DATABASE_URL);
    if (!shouldRun) {
      console.log('Skipping postgres test - DATABASE_URL not set');
      return;
    }

    process.env.GRIDPILOT_API_PERSISTENCE = 'postgres';

    const { AchievementPersistenceModule } = await import('./AchievementPersistenceModule');

    const module: TestingModule = await Test.createTestingModule({
      imports: [AchievementPersistenceModule],
    }).compile();

    const repository = module.get<AchievementRepository>(ACHIEVEMENT_REPOSITORY_TOKEN);
    // The adapter should provide the domain interface methods
    expect(repository).toBeDefined();
    expect(typeof repository.createAchievement).toBe('function');
    expect(typeof repository.findAchievementById).toBe('function');
    expect(typeof repository.findAllAchievements).toBe('function');
  });

  it('defaults to inmemory when GRIDPILOT_API_PERSISTENCE is not set', async () => {
    // Ensure env var is not set
    delete process.env.GRIDPILOT_API_PERSISTENCE;

    const { AchievementPersistenceModule } = await import('./AchievementPersistenceModule');

    const module: TestingModule = await Test.createTestingModule({
      imports: [AchievementPersistenceModule],
    }).compile();

    const repository = module.get<AchievementRepository>(ACHIEVEMENT_REPOSITORY_TOKEN);
    // The adapter should provide the domain interface methods
    expect(repository).toBeDefined();
    expect(typeof repository.createAchievement).toBe('function');
    expect(typeof repository.findAchievementById).toBe('function');
    expect(typeof repository.findAllAchievements).toBe('function');
  });
});