import {
  Controller,
  Post,
  Body,
  UseGuards,
  Req,
  Logger,
  HttpCode,
  HttpStatus,
} from "@nestjs/common";
import { Throttle } from "@nestjs/throttler";
import type { Request as ExpressRequest } from "express";
import { SkipCsrf } from "../../common/decorators/skip-csrf.decorator";
import { LocalAuthService } from "./local-auth.service";
import { LocalAuthEnabledGuard } from "./local-auth.guard";
import { LocalLoginDto } from "./dto/local-login.dto";
import { LocalSetupDto } from "./dto/local-setup.dto";

@Controller("auth/local")
@UseGuards(LocalAuthEnabledGuard)
export class LocalAuthController {
  private readonly logger = new Logger(LocalAuthController.name);

  constructor(private readonly localAuthService: LocalAuthService) {}

  /**
   * First-time break-glass user creation.
   * Requires BREAKGLASS_SETUP_TOKEN from environment.
   */
  @Post("setup")
  @SkipCsrf()
  @Throttle({ strict: { limit: 5, ttl: 60000 } })
  async setup(@Body() dto: LocalSetupDto, @Req() req: ExpressRequest) {
    const ipAddress = this.getClientIp(req);
    const userAgent = req.headers["user-agent"];

    this.logger.log(`Break-glass setup attempt from ${ipAddress}`);

    const result = await this.localAuthService.setup(
      dto.email,
      dto.name,
      dto.password,
      dto.setupToken,
      ipAddress,
      userAgent
    );

    return {
      user: result.user,
      session: result.session,
    };
  }

  /**
   * Break-glass login with email + password.
   */
  @Post("login")
  @SkipCsrf()
  @HttpCode(HttpStatus.OK)
  @Throttle({ strict: { limit: 10, ttl: 60000 } })
  async login(@Body() dto: LocalLoginDto, @Req() req: ExpressRequest) {
    const ipAddress = this.getClientIp(req);
    const userAgent = req.headers["user-agent"];

    const result = await this.localAuthService.login(dto.email, dto.password, ipAddress, userAgent);

    return {
      user: result.user,
      session: result.session,
    };
  }

  private getClientIp(req: ExpressRequest): string {
    const forwardedFor = req.headers["x-forwarded-for"];
    if (forwardedFor) {
      const ips = Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor;
      return ips?.split(",")[0]?.trim() ?? "unknown";
    }
    return req.ip ?? req.socket.remoteAddress ?? "unknown";
  }
}
