import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { MulterModule } from '@nestjs/platform-express';
import {
  MEDIA_STORAGE_SERVICE,
  MinioMediaStorageService,
} from '../listings/infrastructure/services/media-storage.service';
import { CancelUserDeletionHandler } from './application/commands/cancel-user-deletion/cancel-user-deletion.handler';
import { DisableMfaHandler } from './application/commands/disable-mfa/disable-mfa.handler';
import { ExportUserDataHandler } from './application/commands/export-user-data/export-user-data.handler';
import { ForceDeleteUserHandler } from './application/commands/force-delete-user/force-delete-user.handler';
import { ForgotPasswordHandler } from './application/commands/forgot-password/forgot-password.handler';
import { GenerateKycUploadUrlsHandler } from './application/commands/generate-kyc-upload-urls/generate-kyc-upload-urls.handler';
import { LoginUserHandler } from './application/commands/login-user/login-user.handler';
import { ResetPasswordHandler } from './application/commands/reset-password/reset-password.handler';
import { ProcessScheduledDeletionsHandler } from './application/commands/process-scheduled-deletions/process-scheduled-deletions.handler';
import { RefreshTokenHandler } from './application/commands/refresh-token/refresh-token.handler';
import { RegisterUserHandler } from './application/commands/register-user/register-user.handler';
import { RequestUserDeletionHandler } from './application/commands/request-user-deletion/request-user-deletion.handler';
import { ResendOtpHandler } from './application/commands/resend-otp/resend-otp.handler';
import { SetupMfaHandler } from './application/commands/setup-mfa/setup-mfa.handler';
import { SubmitKycHandler } from './application/commands/submit-kyc/submit-kyc.handler';
import { UpdateProfileHandler } from './application/commands/update-profile/update-profile.handler';
import { UseBackupCodeHandler } from './application/commands/use-backup-code/use-backup-code.handler';
import { VerifyEmailChangeHandler } from './application/commands/verify-email-change/verify-email-change.handler';
import { VerifyKycHandler } from './application/commands/verify-kyc/verify-kyc.handler';
import { VerifyMfaChallengeHandler } from './application/commands/verify-mfa-challenge/verify-mfa-challenge.handler';
import { VerifyMfaSetupHandler } from './application/commands/verify-mfa-setup/verify-mfa-setup.handler';
import { VerifyPhoneChangeHandler } from './application/commands/verify-phone-change/verify-phone-change.handler';
import { GetAgentByUserIdHandler } from './application/queries/get-agent-by-user-id/get-agent-by-user-id.handler';
import { GetMfaStatusHandler } from './application/queries/get-mfa-status/get-mfa-status.handler';
import { GetProfileHandler } from './application/queries/get-profile/get-profile.handler';
import { MFA_CHALLENGE_REPOSITORY } from './domain/repositories/mfa-challenge.repository';
import { REFRESH_TOKEN_REPOSITORY } from './domain/repositories/refresh-token.repository';
import { USER_REPOSITORY } from './domain/repositories/user.repository';
import { PrismaMfaChallengeRepository } from './infrastructure/repositories/prisma-mfa-challenge.repository';
import { PrismaRefreshTokenRepository } from './infrastructure/repositories/prisma-refresh-token.repository';
import { PrismaUserRepository } from './infrastructure/repositories/prisma-user.repository';
import { MfaService } from './infrastructure/services/mfa.service';
import { OAuthService } from './infrastructure/services/oauth.service';
import { TokenService } from './infrastructure/services/token.service';
import { GoogleOAuthStrategy } from './infrastructure/strategies/google-oauth.strategy';
import { JwtStrategy } from './infrastructure/strategies/jwt.strategy';
import { LocalStrategy } from './infrastructure/strategies/local.strategy';
import { ZaloOAuthStrategy } from './infrastructure/strategies/zalo-oauth.strategy';
import { AuthController } from './presentation/controllers/auth.controller';
import { MfaController } from './presentation/controllers/mfa.controller';
import { OAuthController } from './presentation/controllers/oauth.controller';
import { UserDataController } from './presentation/controllers/user-data.controller';

const CommandHandlers = [
  RegisterUserHandler,
  LoginUserHandler,
  RefreshTokenHandler,
  VerifyKycHandler,
  SubmitKycHandler,
  GenerateKycUploadUrlsHandler,
  UpdateProfileHandler,
  VerifyEmailChangeHandler,
  VerifyPhoneChangeHandler,
  ForgotPasswordHandler,
  ResetPasswordHandler,
  ResendOtpHandler,
  RequestUserDeletionHandler,
  CancelUserDeletionHandler,
  ForceDeleteUserHandler,
  ProcessScheduledDeletionsHandler,
  ExportUserDataHandler,
  // MFA
  SetupMfaHandler,
  VerifyMfaSetupHandler,
  VerifyMfaChallengeHandler,
  DisableMfaHandler,
  UseBackupCodeHandler,
];

const QueryHandlers = [GetProfileHandler, GetAgentByUserIdHandler, GetMfaStatusHandler];

@Module({
  imports: [
    CqrsModule,
    PassportModule,
    MulterModule.register({
      limits: { fileSize: 10 * 1024 * 1024 }, // 10 MB — per-type limits enforced by FileValidationPipe
    }),
    JwtModule.registerAsync({
      useFactory: () => {
        const secret = process.env['JWT_SECRET'];
        if (!secret) {
          throw new Error('JWT_SECRET environment variable is required');
        }
        return {
          secret,
          signOptions: { expiresIn: '15m', audience: 'goodgo-api', issuer: 'goodgo-platform' },
        };
      },
    }),
  ],
  controllers: [AuthController, MfaController, OAuthController, UserDataController],
  providers: [
    // Repositories
    { provide: USER_REPOSITORY, useClass: PrismaUserRepository },
    { provide: REFRESH_TOKEN_REPOSITORY, useClass: PrismaRefreshTokenRepository },
    { provide: MFA_CHALLENGE_REPOSITORY, useClass: PrismaMfaChallengeRepository },

    // Storage
    { provide: MEDIA_STORAGE_SERVICE, useClass: MinioMediaStorageService },

    // Strategies
    JwtStrategy,
    LocalStrategy,
    GoogleOAuthStrategy,
    ZaloOAuthStrategy,

    // Services
    TokenService,
    OAuthService,
    MfaService,

    // CQRS
    ...CommandHandlers,
    ...QueryHandlers,
  ],
  exports: [TokenService, OAuthService, MfaService, USER_REPOSITORY],
})
export class AuthModule {}
