import { Module } from '@nestjs/common';

import { LoggingModule } from '../../domain/logging/LoggingModule';

import type { Logger } from '@core/shared/application/Logger';
import type { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import type { StoredUser } from '@core/identity/domain/repositories/IUserRepository';

import { InMemoryAuthRepository } from '@adapters/identity/persistence/inmemory/InMemoryAuthRepository';
import { InMemoryUserRepository } from '@adapters/identity/persistence/inmemory/InMemoryUserRepository';
import { InMemoryPasswordHashingService } from '@adapters/identity/services/InMemoryPasswordHashingService';
import { InMemoryMagicLinkRepository } from '@adapters/identity/persistence/inmemory/InMemoryMagicLinkRepository';

import { AUTH_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN, USER_REPOSITORY_TOKEN, MAGIC_LINK_REPOSITORY_TOKEN } from '../identity/IdentityPersistenceTokens';

@Module({
  imports: [LoggingModule],
  providers: [
    {
      provide: USER_REPOSITORY_TOKEN,
      useFactory: (logger: Logger) => {
        const initialUsers: StoredUser[] = [
          {
            // Match seeded racing driver id so dashboard works in inmemory mode.
            id: 'driver-1',
            email: 'admin@gridpilot.local',
            passwordHash: 'demo_salt_321nimda', // InMemoryPasswordHashingService: "admin123" reversed.
            displayName: 'Admin',
            createdAt: new Date(),
          },
        ];
        return new InMemoryUserRepository(logger, initialUsers);
      },
      inject: ['Logger'],
    },
    {
      provide: AUTH_REPOSITORY_TOKEN,
      useFactory: (userRepository: InMemoryUserRepository, passwordHashingService: IPasswordHashingService, logger: Logger) =>
        new InMemoryAuthRepository(userRepository, passwordHashingService, logger),
      inject: [USER_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN, 'Logger'],
    },
    {
      provide: PASSWORD_HASHING_SERVICE_TOKEN,
      useClass: InMemoryPasswordHashingService,
    },
    {
      provide: MAGIC_LINK_REPOSITORY_TOKEN,
      useFactory: (logger: Logger) => new InMemoryMagicLinkRepository(logger),
      inject: ['Logger'],
    },
  ],
  exports: [USER_REPOSITORY_TOKEN, AUTH_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN, MAGIC_LINK_REPOSITORY_TOKEN],
})
export class InMemoryIdentityPersistenceModule {}