import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { DataSourceOptions } from 'typeorm';
import { IncidentCaseEntity } from '../incidents/incident-case.entity';
import { MonitorAgentEntity } from '../monitoring/monitor-agent.entity';
import { MonitorAlertEntity } from '../monitoring/monitor-alert.entity';
import { MonitorLogEventEntity } from '../monitoring/monitor-log-event.entity';
import { MonitorRunEntity } from '../monitoring/monitor-run.entity';
import { MonitorTargetEntity } from '../monitoring/monitor-target.entity';
import { InspectionRunEntity } from '../runs/inspection-run.entity';
import { InspectionTaskEntity } from '../tasks/inspection-task.entity';

export type SupportedDatabaseClient = 'mariadb' | 'kingbase';

export function buildDataSourceOptions(
  configService: ConfigService,
  overrides?: Partial<DataSourceOptions>,
): DataSourceOptions {
  const read = (key: string, fallback: string) =>
    String(configService.get<string>(key) ?? fallback);
  const client =
    (configService.get<string>('DB_CLIENT') as
      | SupportedDatabaseClient
      | undefined) ?? 'mariadb';

  const common = {
    host: read('DB_HOST', '127.0.0.1'),
    port: Number(
      configService.get<string>('DB_PORT') ??
        (client === 'kingbase' ? '54321' : '3306'),
    ),
    username: read('DB_USERNAME', 'sentai'),
    password: read('DB_PASSWORD', 'sentai123'),
    database: read('DB_DATABASE', 'sentai'),
    synchronize:
      (configService.get<string>('DB_SYNCHRONIZE') ?? 'false') === 'true',
    logging: false,
    entities: [
      InspectionTaskEntity,
      InspectionRunEntity,
      IncidentCaseEntity,
      MonitorAgentEntity,
      MonitorAlertEntity,
      MonitorLogEventEntity,
      MonitorTargetEntity,
      MonitorRunEntity,
    ],
  };

  if (client === 'kingbase') {
    const postgresOptions = {
      type: 'postgres',
      ...common,
      schema: 'public',
    };
    return {
      ...postgresOptions,
      ...overrides,
    } as unknown as DataSourceOptions;
  }

  const mysqlOptions = {
    type: 'mariadb',
    ...common,
  };

  return {
    ...mysqlOptions,
    ...overrides,
  } as unknown as DataSourceOptions;
}

export function buildDatabaseOptions(
  configService: ConfigService,
): TypeOrmModuleOptions {
  return buildDataSourceOptions(configService);
}
