import { Module, type OnApplicationShutdown, Inject, Optional } from '@nestjs/common';
import { createQueue, type QueueHandle } from '@mosaicstack/queue';
import type { MosaicConfig } from '@mosaicstack/config';
import { MOSAIC_CONFIG } from '../config/config.module.js';
import { SessionGCService } from './session-gc.service.js';
import { REDIS } from './gc.tokens.js';

const GC_QUEUE_HANDLE = 'GC_QUEUE_HANDLE';

@Module({
  providers: [
    {
      provide: GC_QUEUE_HANDLE,
      useFactory: (config: MosaicConfig | null): QueueHandle | null => {
        // On Local tier there is no Redis — skip the ioredis connection entirely.
        // The Valkey GC sweep is a no-op on Local (no session keys stored there).
        if (config?.queue?.type === 'local') return null;
        return createQueue();
      },
      inject: [MOSAIC_CONFIG],
    },
    {
      provide: REDIS,
      useFactory: (handle: QueueHandle | null) => handle?.redis ?? null,
      inject: [GC_QUEUE_HANDLE],
    },
    SessionGCService,
  ],
  exports: [SessionGCService],
})
export class GCModule implements OnApplicationShutdown {
  constructor(
    @Optional()
    @Inject(GC_QUEUE_HANDLE)
    private readonly handle: QueueHandle | null,
  ) {}

  async onApplicationShutdown(): Promise<void> {
    await this.handle?.close().catch(() => {});
  }
}
