// jwt-auth.guard.ts
import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Reflector } from '@nestjs/core';
import { swaggerApiKeys } from 'src/config/common';
import { IS_PUBLIC_KEY } from './public.decorator';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest();
    const headers = request.headers;
    const token = this.extractToken(headers);

    // Skip JWT for prerender requests
    if (headers['x-prerender-skip'] === '1') {
      return true;
    }

    // Skip JWT for bot user agents
    const ua = (headers['user-agent'] || '').toLowerCase();
    const bots = [
      // Google crawlers
      'googlebot',
      'googlebot-image',
      'googlebot-news',
      'googlebot-video',
      'googlebot-mobile',
      'mediapartners-google',
      'adsbot-google',
      'adsbot-google-mobile',
      'apis-google',
      'storebot-google',
      'google-inspectiontool',
      'google-safety',
      'feedfetcher-google',
      // Other search engines
      'bingbot',
      'yandex',
      'baiduspider',
      'duckduckbot',
      'applebot',
      'semrushbot',
      'ahrefsbot',
      'mj12bot',
      // Social media crawlers
      'facebookexternalhit',
      'twitterbot',
      'linkedinbot',
      'slackbot',
      'discordbot',
      'whatsapp',
      'telegrambot',
    ];
    if (bots.some((bot) => ua.includes(bot))) {
      return true;
    }

    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    if (token === swaggerApiKeys) {
      return true;
    }
    return super.canActivate(context);
  }

  private extractToken(headers: any): string | null {
    const authorizationHeader =
      headers['authorization'] || headers['Authorization'];
    if (!authorizationHeader) return null;

    const parts = authorizationHeader.split(' ');
    if (parts.length !== 2 || parts[0] !== 'Bearer') return null;

    return parts[1];
  }
}
