import {
  Controller,
  Get,
  Query,
  Headers,
  UnauthorizedException,
  ParseIntPipe,
  DefaultValuePipe,
  Logger,
} from '@nestjs/common';
import { GetMyReferralInfoUseCase } from '../../../application/use-cases/get-my-referral-info.use-case';
import { ValidateReferralCodeUseCase } from '../../../application/use-cases/validate-referral-code.use-case';
import { GetReferralListUseCase } from '../../../application/use-cases/get-referral-list.use-case';
import * as jwt from 'jsonwebtoken';

/**
 * User-facing referral endpoints.
 * Kong enforces JWT — we extract tenant/user from the Authorization header here.
 */
@Controller('api/v1/referral')
export class ReferralController {
  private readonly logger = new Logger(ReferralController.name);

  constructor(
    private readonly getMyReferralInfo: GetMyReferralInfoUseCase,
    private readonly validateCode: ValidateReferralCodeUseCase,
    private readonly getReferralList: GetReferralListUseCase,
  ) {}

  /** GET /api/v1/referral/me — get current tenant's referral info & code */
  @Get('me')
  async getMe(@Headers('authorization') auth: string) {
    const { tenantId, userId } = this.extractJwt(auth);
    return this.getMyReferralInfo.execute(tenantId, userId);
  }

  /** GET /api/v1/referral/me/referrals?limit=20&offset=0 — list direct referrals */
  @Get('me/referrals')
  async getMyReferrals(
    @Headers('authorization') auth: string,
    @Query('limit', new DefaultValuePipe(20), ParseIntPipe) limit: number,
    @Query('offset', new DefaultValuePipe(0), ParseIntPipe) offset: number,
  ) {
    const { tenantId } = this.extractJwt(auth);
    return this.getReferralList.getReferrals(tenantId, Math.min(limit, 100), offset);
  }

  /** GET /api/v1/referral/me/rewards?status=PENDING&limit=20&offset=0 */
  @Get('me/rewards')
  async getMyRewards(
    @Headers('authorization') auth: string,
    @Query('status') status: 'PENDING' | 'APPLIED' | 'EXPIRED' | undefined,
    @Query('limit', new DefaultValuePipe(20), ParseIntPipe) limit: number,
    @Query('offset', new DefaultValuePipe(0), ParseIntPipe) offset: number,
  ) {
    const { tenantId } = this.extractJwt(auth);
    return this.getReferralList.getRewards(tenantId, status, Math.min(limit, 100), offset);
  }

  /** GET /api/v1/referral/validate/:code — public, validate a referral code */
  @Get('validate')
  async validate(@Query('code') code: string) {
    return this.validateCode.execute(code ?? '');
  }

  private extractJwt(auth: string): { tenantId: string; userId: string } {
    if (!auth?.startsWith('Bearer ')) {
      throw new UnauthorizedException('Missing authorization header');
    }
    const token = auth.slice(7);
    const secret = process.env.JWT_SECRET || 'dev-secret';
    try {
      const payload = jwt.verify(token, secret) as any;
      return {
        tenantId: payload.tenantId,
        userId: payload.sub,
      };
    } catch {
      throw new UnauthorizedException('Invalid JWT');
    }
  }
}
