/**
 * CSRF Controller
 *
 * Provides CSRF token generation endpoint for client applications.
 * Tokens are cryptographically bound to the user session via HMAC.
 */

import { Controller, Get, Res, Req, UseGuards } from "@nestjs/common";
import { Response, Request } from "express";
import { SkipCsrf } from "../decorators/skip-csrf.decorator";
import { CsrfService } from "../services/csrf.service";
import { AuthGuard } from "../../auth/guards/auth.guard";
import type { AuthenticatedUser } from "../types/user.types";

interface AuthenticatedRequest extends Request {
  user?: AuthenticatedUser;
}

@Controller("v1/csrf")
export class CsrfController {
  constructor(private readonly csrfService: CsrfService) {}

  /**
   * Generate and set CSRF token bound to user session
   * Requires authentication to bind token to session
   * Returns token to client and sets it in httpOnly cookie
   */
  @Get("token")
  @UseGuards(AuthGuard)
  @SkipCsrf() // This endpoint itself doesn't need CSRF protection
  getCsrfToken(
    @Req() request: AuthenticatedRequest,
    @Res({ passthrough: true }) response: Response
  ): { token: string } {
    // Get user ID from authenticated request
    const userId = request.user?.id;

    if (!userId) {
      // This should not happen if AuthGuard is working correctly
      throw new Error("User ID not available after authentication");
    }

    // Generate session-bound CSRF token
    const token = this.csrfService.generateToken(userId);

    // Set token in httpOnly cookie
    response.cookie("csrf-token", token, {
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "strict",
      maxAge: 24 * 60 * 60 * 1000, // 24 hours
    });

    // Return token to client (so it can include in X-CSRF-Token header)
    return { token };
  }
}
