import 'reflect-metadata';

import { MODULE_METADATA } from '@nestjs/common/constants';
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import { afterEach, describe, expect, it, vi } from 'vitest';

import { SOCIAL_FEED_REPOSITORY_TOKEN, SOCIAL_GRAPH_REPOSITORY_TOKEN } from './SocialPersistenceTokens';

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

  afterEach(() => {
    process.env = originalEnv;
    vi.restoreAllMocks();
  });

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

    process.env.GRIDPILOT_API_PERSISTENCE = 'inmemory';
    delete process.env.DATABASE_URL;

    const { SocialPersistenceModule } = await import('./SocialPersistenceModule');
    const { InMemoryFeedRepository } = await import('@adapters/social/persistence/inmemory/InMemorySocialAndFeed');
    const { InMemorySocialGraphRepository } = await import('@adapters/social/persistence/inmemory/InMemorySocialAndFeed');

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

    const feedRepo = module.get(SOCIAL_FEED_REPOSITORY_TOKEN);
    const socialRepo = module.get(SOCIAL_GRAPH_REPOSITORY_TOKEN);

    expect(feedRepo).toBeInstanceOf(InMemoryFeedRepository);
    expect(socialRepo).toBeInstanceOf(InMemorySocialGraphRepository);

    await module.close();
  });

  it('uses postgres module when GRIDPILOT_API_PERSISTENCE=postgres', async () => {
    vi.resetModules();

    process.env.GRIDPILOT_API_PERSISTENCE = 'postgres';
    delete process.env.DATABASE_URL;

    const { SocialPersistenceModule } = await import('./SocialPersistenceModule');
    const { PostgresSocialPersistenceModule } = await import('../postgres/PostgresSocialPersistenceModule');

    const imports = Reflect.getMetadata(MODULE_METADATA.IMPORTS, SocialPersistenceModule) as unknown[];
    expect(imports).toContain(PostgresSocialPersistenceModule);
  });
});