/**
 * Region 验证守卫
 * 
 * 验证请求头中的 X-Region-Id 是否有效
 */

import {
  Injectable,
  CanActivate,
  ExecutionContext,
  Logger,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import {
  REGION_REQUIRED_KEY,
  SUPPORTED_REGIONS,
  RegionId,
} from '../decorators/region.decorator';
import {
  RegionRequiredException,
  InvalidRegionException,
} from '../exceptions';

@Injectable()
export class RegionGuard implements CanActivate {
  private readonly logger = new Logger(RegionGuard.name);

  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    // 检查是否需要区域验证
    const regionRequired = this.reflector.getAllAndOverride<boolean>(
      REGION_REQUIRED_KEY,
      [context.getHandler(), context.getClass()],
    );

    // 如果明确标记为不需要区域验证，则跳过
    if (regionRequired === false) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const regionId = request.headers['x-region-id'];

    // 如果没有提供区域 ID
    if (!regionId) {
      // 默认情况下需要区域验证
      throw new RegionRequiredException();
    }

    // 验证区域 ID 是否有效
    if (!this.isValidRegion(regionId)) {
      throw new InvalidRegionException(regionId);
    }

    // 将验证后的 regionId 附加到请求对象
    request.regionId = regionId.toUpperCase() as RegionId;

    this.logger.debug(`Request region validated: ${request.regionId}`);

    return true;
  }

  private isValidRegion(regionId: string): boolean {
    return SUPPORTED_REGIONS.includes(regionId.toUpperCase() as RegionId);
  }
}
