import { Module } from '@nestjs/common';
import { TypeOrmModule, getDataSourceToken } from '@nestjs/typeorm';
import type { DataSource } from 'typeorm';

import { LoggingModule } from '../../domain/logging/LoggingModule';
import { SOCIAL_FEED_REPOSITORY_TOKEN, SOCIAL_GRAPH_REPOSITORY_TOKEN } from '../social/SocialPersistenceTokens';

import { DriverOrmEntity } from '@adapters/racing/persistence/typeorm/entities/DriverOrmEntity';
import { DriverOrmMapper } from '@adapters/racing/persistence/typeorm/mappers/DriverOrmMapper';

import { FeedItemOrmEntity } from '@adapters/social/persistence/typeorm/entities/FeedItemOrmEntity';
import { FriendshipOrmEntity } from '@adapters/social/persistence/typeorm/entities/FriendshipOrmEntity';
import { FeedItemOrmMapper } from '@adapters/social/persistence/typeorm/mappers/FeedItemOrmMapper';
import { TypeOrmFeedRepository } from '@adapters/social/persistence/typeorm/repositories/TypeOrmFeedRepository';
import { TypeOrmSocialGraphRepository } from '@adapters/social/persistence/typeorm/repositories/TypeOrmSocialGraphRepository';

const typeOrmFeatureImports = [
  TypeOrmModule.forFeature([FeedItemOrmEntity, FriendshipOrmEntity, DriverOrmEntity]),
];

@Module({
  imports: [LoggingModule, ...typeOrmFeatureImports],
  providers: [
    { provide: FeedItemOrmMapper, useFactory: () => new FeedItemOrmMapper() },
    { provide: DriverOrmMapper, useFactory: () => new DriverOrmMapper() },

    {
      provide: SOCIAL_FEED_REPOSITORY_TOKEN,
      useFactory: (dataSource: DataSource, mapper: FeedItemOrmMapper) =>
        new TypeOrmFeedRepository(
          dataSource.getRepository(FeedItemOrmEntity),
          dataSource.getRepository(FriendshipOrmEntity),
          mapper,
        ),
      inject: [getDataSourceToken(), FeedItemOrmMapper],
    },
    {
      provide: SOCIAL_GRAPH_REPOSITORY_TOKEN,
      useFactory: (dataSource: DataSource, driverMapper: DriverOrmMapper) =>
        new TypeOrmSocialGraphRepository(
          dataSource.getRepository(FriendshipOrmEntity),
          dataSource.getRepository(DriverOrmEntity),
          driverMapper,
        ),
      inject: [getDataSourceToken(), DriverOrmMapper],
    },
  ],
  exports: [SOCIAL_FEED_REPOSITORY_TOKEN, SOCIAL_GRAPH_REPOSITORY_TOKEN],
})
export class PostgresSocialPersistenceModule {}