import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { UserService } from '../user/user.service';
import { Request } from 'express';
import { IS_PUBLIC_KEY } from './public.decorator';

@Injectable()
export class ApiKeyGuard implements CanActivate {
    constructor(
        private reflector: Reflector,
        private userService: UserService,
    ) { }

    async canActivate(context: ExecutionContext): Promise<boolean> {
        const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);
        if (isPublic) {
            return true;
        }

        const request = context.switchToHttp().getRequest<Request & { user?: any, tenantId?: string }>();
        const apiKey = this.extractApiKeyFromHeader(request);

        if (apiKey) {
            const user = await this.userService.findByApiKey(apiKey);
            if (user) {
                request.user = user;
                request.tenantId = user.tenantId;
                return true;
            }
            throw new UnauthorizedException('Invalid API key');
        }

        throw new UnauthorizedException('Missing API key');
    }

    private extractApiKeyFromHeader(request: Request): string | undefined {
        const authHeader = request.headers.authorization;
        if (authHeader && authHeader.startsWith('Bearer kb_')) {
            return authHeader.substring(7, authHeader.length);
        }
        const headerKey = request.headers['x-api-key'] as string;
        if (headerKey) return headerKey;

        return undefined;
    }
}
