import {
  Controller,
  Post,
  Get,
  Body,
  Param,
  UseGuards,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { InternalApiGuard } from '../guards/internal-api.guard';
import { RegisterWithCodeUseCase } from '../../../application/use-cases/register-with-code.use-case';
import { GetPendingCreditsUseCase } from '../../../application/use-cases/get-pending-credits.use-case';

/**
 * Internal service-to-service endpoints.
 * Protected by X-Internal-Api-Key header (InternalApiGuard).
 * NOT exposed through Kong to the outside world.
 *
 * Called by:
 *   - auth-service: on tenant registration → POST /api/v1/referral/internal/register
 *   - billing-service: before invoice → GET /api/v1/referral/internal/:tenantId/pending-credits
 *   - billing-service: after invoice → POST /api/v1/referral/internal/:tenantId/apply-credits
 */
@Controller('api/v1/referral/internal')
@UseGuards(InternalApiGuard)
export class ReferralInternalController {
  constructor(
    private readonly registerWithCode: RegisterWithCodeUseCase,
    private readonly getPendingCredits: GetPendingCreditsUseCase,
  ) {}

  /**
   * Called by auth-service immediately after a new tenant is created.
   * Creates the tenant's own referral code and optionally links a referrer.
   */
  @Post('register')
  @HttpCode(HttpStatus.OK)
  async register(
    @Body() body: { tenantId: string; userId: string; referralCode?: string },
  ) {
    return this.registerWithCode.execute({
      tenantId: body.tenantId,
      userId: body.userId,
      referralCode: body.referralCode,
    });
  }

  /**
   * Called by billing-service before generating an invoice.
   * Returns total pending credit and individual reward IDs.
   */
  @Get(':tenantId/pending-credits')
  async getPending(@Param('tenantId') tenantId: string) {
    return this.getPendingCredits.getPending(tenantId);
  }

  /**
   * Called by billing-service after applying credits to an invoice.
   * Marks reward records as APPLIED.
   */
  @Post(':tenantId/apply-credits')
  @HttpCode(HttpStatus.OK)
  async applyCredits(
    @Param('tenantId') tenantId: string,
    @Body() body: { invoiceId: string; appliedCents: number },
  ) {
    await this.getPendingCredits.markApplied(tenantId, body.invoiceId, body.appliedCents);
    return { success: true };
  }
}
