import type { MikroOrmModuleAsyncOptions } from '@mikro-orm/nestjs';
import { ConfigService } from '@nestjs/config';
import { PostgreSqlDriver } from '@mikro-orm/postgresql';
// import { defineConfig } from '@mikro-orm/postgresql';

import type { Logger } from '@nestjs/common';
import { MIKRO_ORM_QUERY_LOGGER } from '../common/constants';
import { mikroOrmQueryLoggerProvider } from '../common/providers/mikro-orm-logger.provider';

const dataBaseConfig: MikroOrmModuleAsyncOptions = {
 
  inject: [ConfigService, MIKRO_ORM_QUERY_LOGGER],
  providers: [mikroOrmQueryLoggerProvider],
  useFactory: (configService: ConfigService, logger: Logger) => {
    const DB_PASS = configService.getOrThrow<string>('DB_PASS');
    const DB_USER = configService.getOrThrow<string>('DB_USER');
    const DB_HOST = configService.getOrThrow<string>('DB_HOST');
    const DB_PORT = configService.getOrThrow<number>('DB_PORT');
    const DB_NAME = configService.getOrThrow<string>('DB_NAME');
    const encodedPassword = encodeURIComponent(DB_PASS);
    const isProduction = configService.getOrThrow<string>('NODE_ENV') === 'production';

    return {
      // entities: ['dist/**/*.entity.js'],
      entitiesTs: ['src/**/*.entity.ts'],
      driver: PostgreSqlDriver,
      autoLoadEntities: true,
      dbName: DB_NAME,
      debug: false,
      clientUrl: `postgres://${DB_USER}:${encodedPassword}@${DB_HOST}:${DB_PORT}`,
      ensureDatabase: isProduction
        ? false
        : {
            forceCheck: true,
            create: true,
            schema: 'update',
          },
      forceUtcTimezone: true,
      pool: {
        min: isProduction ? 30 : 5,
        max: isProduction ? 100 : 50,
        idleTimeoutMillis: 30000,
        acquireTimeoutMillis: 30000,
        reapIntervalMillis: 1000,
        createTimeoutMillis: 15000,
        destroyTimeoutMillis: 5000,
      },
      logger: isProduction ? message => logger.log(message) : message => logger.debug(message),
      schemaGenerator: {
        // createForeignKey: !isProduction,
        disableForeignKeys: false,
        // createIndex: true,
      },
      migrations: {
        path: './database/migrations',
        pathTs: './database/migrations',
        tableName: 'migrations',
        transactional: true,
        allOrNothing: true,
        dropTables: false,
        safe: true,
        emit: 'ts',
      },
      connect: true,
      registerRequestContext: true,
      driverOptions: {
        connection: {
          keepAlive: true,
          keepAliveInitialDelayMillis: 10000,
          statement_timeout: 60000,
          query_timeout: 60000,
          idle_in_transaction_session_timeout: 60000,
          connectionTimeoutMillis: 10000,
          application_name: configService.getOrThrow<string>('DB_NAME'),
        },
        connectionRetries: 5,
        connectionRetryDelay: 3000,
        validateConnection: (connection: any) => {
          try {
            // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
            return !!(connection && !connection.closed);
          } catch (e: unknown) {
            logger.error(`Connection validation failed: ${(e as Error).message}`);
            return false;
          }
        },
        poolErrorHandler: (err: Error) => {
          logger.error(`PostgreSQL pool error: ${err.message}`);
          if (err.message.includes('ECONNRESET') || err.message.includes('Connection terminated unexpectedly')) {
            logger.warn('Connection reset detected, will attempt to reconnect');
            return true;
          }
          return false;
        },
      },
    };
  },
};

export default dataBaseConfig;
