import { Injectable, ExecutionContext } from "@nestjs/common";
import type { Request, Response } from "express";
import {
  AuthRateLimitService,
  type RateLimitOutcome,
} from "../../../infra/rate-limiting/auth-rate-limit.service";

export type RequestWithRateLimit = Request & { __authRateLimit?: RateLimitOutcome };

@Injectable()
export class FailedLoginThrottleGuard {
  constructor(private readonly authRateLimitService: AuthRateLimitService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest<RequestWithRateLimit>();

    const outcome = await this.authRateLimitService.consumeLoginAttempt(request);
    request.__authRateLimit = outcome;

    return true;
  }

  // Method to be called after login attempt to handle success/failure
  async handleLoginResult(request: Request, wasSuccessful: boolean): Promise<void> {
    if (wasSuccessful) {
      await this.authRateLimitService.clearLoginAttempts(request);
    }
  }

  static applyRateLimitHeaders(request: RequestWithRateLimit, response: Response): void {
    const outcome = request.__authRateLimit;
    if (!outcome) return;

    response.setHeader("X-RateLimit-Remaining", String(outcome.remainingPoints));
    response.setHeader("X-RateLimit-Reset", String(Math.ceil(outcome.msBeforeNext / 1000)));
    response.setHeader("X-Auth-Captcha", outcome.needsCaptcha ? "required" : "optional");
  }
}
