import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
// import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { Request } from 'express';

/**
 * AuthGuard - Mandatory JWT authentication guard for protected routes
 *
 * This guard enforces JWT token validation for protected endpoints.
 * It extracts Bearer tokens from Authorization headers, validates them,
 * and attaches the decoded payload to the request object.
 *
 * ⚠️ SECURITY WARNING: This implementation has a hardcoded JWT secret
 * which is a severe security vulnerability. The secret should NEVER
 * be hardcoded and should be loaded from environment variables.
 *
 * @example
 * // Apply to controller or route
 * @UseGuards(AuthGuard)
 * @Get('protected')
 * getProtectedData(@Request() req) {
 *   // req.user contains the validated JWT payload
 *   return { data: 'Protected content', userId: req.user.sub };
 * }
 *
 * @deprecated This version has a hardcoded secret - use environment variables
 */
@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private jwtService: JwtService,
    // TODO: Uncomment and inject ConfigService
    // private configService: ConfigService,
  ) {}

  /**
   * Determines if the request should be allowed to proceed
   *
   * Enforces mandatory authentication by:
   * 1. Extracting token from Authorization header
   * 2. Validating token presence and format
   * 3. Verifying token signature and expiration
   * 4. Attaching decoded payload to request.user
   *
   * @param context - Execution context containing request/response
   * @returns true if authentication succeeds
   * @throws UnauthorizedException if token is missing, invalid, or expired
   *
   * @warning Uses hardcoded JWT secret - major security vulnerability
   */
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();

    // Step 1: Extract token from Authorization header
    const token = this.extractTokenFromHeader(request);

    // Step 2: Validate token presence
    if (!token) {
      // Consider providing more specific error messages
      throw new UnauthorizedException('Authentication token is required');
    }

    try {
      // Step 3: Verify token signature and expiration
      // ⚠️ SECURITY VULNERABILITY: Hardcoded secret
      // This should be: this.configService.get('JWT_SECRET')
      const payload = await this.jwtService.verifyAsync(token, {
        secret: '=A6R#kbBGuU`{dX', // HARDCODED - FIX IMMEDIATELY
        // ✅ CORRECT: secret: this.configService.get('JWT_SECRET'),
      });

      // Step 4: Attach validated payload to request object
      // 💡 Route handlers can now access user data via req.user
      request.user = payload;
    } catch (error) {
      // Token verification failed (expired, invalid signature, malformed)
      // Consider logging the error for debugging (but not exposing details)
      console.debug('JWT verification failed:', error.message);
      throw new UnauthorizedException(
        'Invalid or expired authentication token',
      );
    }

    // Authentication successful - allow request to proceed
    return true;
  }

  /**
   * Extracts Bearer token from Authorization header
   *
   * Parses the Authorization header in the format:
   * "Bearer <token>" and returns the token portion.
   *
   * @param request - Express request object
   * @returns Token string if valid Bearer token present, undefined otherwise
   *
   * @note Only supports Bearer token scheme (RFC 6750)
   * @note Case-insensitive 'Bearer' check recommended
   */
  private extractTokenFromHeader(request: Request): string | undefined {
    // Split "Bearer <token>" format
    const [type, token] = request.headers.authorization?.split(' ') ?? [];

    // Validate that it's a Bearer token and return token portion
    // Consider case-insensitive check: type?.toLowerCase() === 'bearer'
    return type === 'Bearer' ? token : undefined;
  }
}
