import {
  BadRequestException,
  Controller,
  Headers,
  HttpCode,
  Post,
  Req,
  type RawBodyRequest,
} from '@nestjs/common'
import { StripeClient } from '../integrations/stripe.client.js'
import { BillingService } from './billing.service.js'

// Stripe webhook receiver. NOT guarded (Stripe calls it) — authenticity comes
// from signature verification against the raw body. No-ops when Stripe is
// disabled so the route is safe to expose in dev.
@Controller('stripe')
export class StripeWebhookController {
  constructor(
    private readonly stripe: StripeClient,
    private readonly billing: BillingService,
  ) {}

  @Post('webhook')
  @HttpCode(200)
  async webhook(
    // Only req.rawBody is needed; the signature comes via @Headers. Typed
    // minimally to avoid a direct 'fastify' type import (transitive dep).
    @Req() req: RawBodyRequest<Record<string, unknown>>,
    @Headers('stripe-signature') signature: string,
  ) {
    if (!this.stripe.enabled || !this.stripe.hasWebhookSecret) {
      return { received: true, ignored: 'stripe disabled' }
    }
    if (!req.rawBody || !signature) {
      throw new BadRequestException('Missing raw body or stripe-signature header')
    }
    let event
    try {
      event = this.stripe.constructWebhookEvent(req.rawBody, signature)
    } catch {
      throw new BadRequestException('Invalid Stripe signature')
    }
    await this.billing.handleWebhookEvent(event)
    return { received: true }
  }
}
