import { DynamicModule, Global, Module, Logger } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtHelper } from './jwt.helper';
import { AuthMiddleware } from './auth.middleware';
import { AagModule, AagService } from '@nxtoai/aag';
import { GatiModule } from '@nxtoai/gati';
import { JwtService } from './jwt.service';

export interface JwtetteModuleOptions {
    /**
     * JWT secret key
     * @default process.env.JWT_SECRET
     */
    secret?: string;

    /**
     * JWT token expiration time
     * @default '24h'
     */
    expiresIn?: string;

    /**
     * Endpoints to skip JWT validation
     * @default []
     */
    skipJwtEndpoints?: string[];

    /**
     * AeroSpike configuration
     */
    aerospike?: {
        hosts: string[];
        namespace: string;
        port: number;
        timeout: number;
        maxSockets: number;
        maxConnsPerNode: number;
        user?: string;
        password?: string;
    };
}

@Global()
@Module({})
export class JwtetteModule {
    static forRoot(options: JwtetteModuleOptions = {}): DynamicModule {
        const aagOptions = {
            level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
            filename: process.env.LOG_FILE || 'logs/app.log',
            debugUsers: process.env.LOGETTE_DEBUG_USERS?.split(',') || [],
        };

        return {
            module: JwtetteModule,
            imports: [
                ConfigModule,
                JwtModule.registerAsync({
                    imports: [ConfigModule],
                    useFactory: (configService: ConfigService) => ({
                        secret: options.secret || configService.get('JWT_SECRET'),
                        signOptions: { expiresIn: options.expiresIn || '24h' },
                    }),
                    inject: [ConfigService],
                }),
                AagModule.forRoot(aagOptions),
                GatiModule.forRoot({
                    hosts: options.aerospike?.hosts || [process.env.AEROSPIKE_HOSTS || 'localhost'],
                    namespace: options.aerospike?.namespace || process.env.AEROSPIKE_NAMESPACE || 'test',
                    port: options.aerospike?.port || parseInt(process.env.AEROSPIKE_PORT || '3000', 10),
                    timeout: options.aerospike?.timeout || parseInt(process.env.AEROSPIKE_TIMEOUT || '1000', 10),
                    maxSockets: options.aerospike?.maxSockets || parseInt(process.env.AEROSPIKE_MAX_SOCKETS || '100', 10),
                    maxConnsPerNode: options.aerospike?.maxConnsPerNode || parseInt(process.env.AEROSPIKE_MAX_CONNS || '100', 10),
                    user: options.aerospike?.user || process.env.AEROSPIKE_USER,
                    password: options.aerospike?.password || process.env.AEROSPIKE_PASSWORD
                }),
            ],
            providers: [
                {
                    provide: 'JWTETTE_MODULE_OPTIONS',
                    useValue: options,
                },
                {
                    provide: 'AAG_OPTIONS',
                    useValue: aagOptions,
                },
                JwtHelper,
                AuthMiddleware,
                JwtService,
                AagService,
            ],
            exports: [JwtHelper, AuthMiddleware, JwtService, AagService],
        };
    }
} 