// src/services/db/index.db.test.ts
import { describe, it, expect, vi } from 'vitest';

// Mock all the repository classes to be simple classes/functions
// This prevents their constructors from running real database connection logic.
vi.mock('./user.db', () => ({ UserRepository: class UserRepository {} }));
vi.mock('./flyer.db', () => ({ FlyerRepository: class FlyerRepository {} }));
vi.mock('./address.db', () => ({ AddressRepository: class AddressRepository {} }));
vi.mock('./shopping.db', () => ({ ShoppingRepository: class ShoppingRepository {} }));
vi.mock('./personalization.db', () => ({
  PersonalizationRepository: class PersonalizationRepository {},
}));
vi.mock('./recipe.db', () => ({ RecipeRepository: class RecipeRepository {} }));
vi.mock('./notification.db', () => ({
  NotificationRepository: class NotificationRepository {},
}));
vi.mock('./budget.db', () => ({ BudgetRepository: class BudgetRepository {} }));
vi.mock('./gamification.db', () => ({
  GamificationRepository: class GamificationRepository {},
}));
vi.mock('./admin.db', () => ({ AdminRepository: class AdminRepository {} }));
vi.mock('./upc.db', () => ({ UpcRepository: class UpcRepository {} }));
vi.mock('./expiry.db', () => ({ ExpiryRepository: class ExpiryRepository {} }));
vi.mock('./receipt.db', () => ({ ReceiptRepository: class ReceiptRepository {} }));

// These modules export an already-instantiated object, so we mock the object.
vi.mock('./reaction.db', () => ({ reactionRepo: {} }));
vi.mock('./conversion.db', () => ({ conversionRepo: {} }));

// Mock the re-exported function and getPool.
vi.mock('./connection.db', () => ({
  withTransaction: vi.fn(),
  getPool: vi.fn(() => ({ query: vi.fn() })),
}));

// We must un-mock the file we are testing so we get the actual implementation.
vi.unmock('./index.db');

// Import the module to be tested AFTER setting up the mocks.
import * as db from './index.db';

// Import the mocked classes to check `instanceof`.
import { UserRepository } from './user.db';
import { FlyerRepository } from './flyer.db';
import { AddressRepository } from './address.db';
import { ShoppingRepository } from './shopping.db';
import { PersonalizationRepository } from './personalization.db';
import { RecipeRepository } from './recipe.db';
import { NotificationRepository } from './notification.db';
import { BudgetRepository } from './budget.db';
import { GamificationRepository } from './gamification.db';
import { AdminRepository } from './admin.db';
import { UpcRepository } from './upc.db';
import { ExpiryRepository } from './expiry.db';
import { ReceiptRepository } from './receipt.db';

describe('DB Index', () => {
  it('should instantiate and export all repositories and functions', () => {
    expect(db.userRepo).toBeInstanceOf(UserRepository);
    expect(db.flyerRepo).toBeInstanceOf(FlyerRepository);
    expect(db.addressRepo).toBeInstanceOf(AddressRepository);
    expect(db.shoppingRepo).toBeInstanceOf(ShoppingRepository);
    expect(db.personalizationRepo).toBeInstanceOf(PersonalizationRepository);
    expect(db.recipeRepo).toBeInstanceOf(RecipeRepository);
    expect(db.notificationRepo).toBeInstanceOf(NotificationRepository);
    expect(db.budgetRepo).toBeInstanceOf(BudgetRepository);
    expect(db.gamificationRepo).toBeInstanceOf(GamificationRepository);
    expect(db.adminRepo).toBeInstanceOf(AdminRepository);
    expect(db.upcRepo).toBeInstanceOf(UpcRepository);
    expect(db.expiryRepo).toBeInstanceOf(ExpiryRepository);
    expect(db.receiptRepo).toBeInstanceOf(ReceiptRepository);
    expect(db.reactionRepo).toBeDefined();
    expect(db.conversionRepo).toBeDefined();
    expect(db.withTransaction).toBeDefined();
  });
});
