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';
import { RegisterUserReferralUseCase } from '../../../application/use-cases/register-user-referral.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 registration):
 *       POST /internal/register           → tenant-level code + B2B relationship
 *       POST /internal/user-register      → user-level code + personal circle relationship
 *   - billing-service:
 *       GET  /internal/:tenantId/pending-credits  → credits to apply to next invoice
 *       POST /internal/:tenantId/apply-credits    → mark credits applied
 */
@Controller('api/v1/referral/internal')
@UseGuards(InternalApiGuard)
export class ReferralInternalController {
  constructor(
    private readonly registerWithCode: RegisterWithCodeUseCase,
    private readonly getPendingCredits: GetPendingCreditsUseCase,
    private readonly registerUserReferral: RegisterUserReferralUseCase,
  ) {}

  /**
   * Called by auth-service after a new TENANT is created (B2B flow).
   * Creates the tenant's own referral code; optionally links a tenant-level 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 auth-service after ANY user registration (B2B or personal).
   * Creates the user's personal referral code; optionally links a personal-circle referrer.
   * userReferralCode must start with "USR-" to distinguish from tenant codes.
   */
  @Post('user-register')
  @HttpCode(HttpStatus.OK)
  async userRegister(
    @Body() body: { userId: string; userReferralCode?: string },
  ) {
    return this.registerUserReferral.execute({
      userId: body.userId,
      userReferralCode: body.userReferralCode,
    });
  }

  /**
   * 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 };
  }
}
