import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Request } from 'express';

// 支持的区域列表
export const SUPPORTED_REGIONS = ['CN', 'US', 'UAE'] as const;
export type Region = typeof SUPPORTED_REGIONS[number];

// 区域 Header 名称
export const REGION_HEADER = 'x-region-id';

// 装饰器 Key
export const SKIP_REGION_CHECK = 'skipRegionCheck';

/**
 * 区域访问 Guard
 * 
 * 功能：
 * 1. 从 Header 中读取当前访问的区域
 * 2. 验证用户是否有权限访问该区域
 * 3. 将区域信息注入到请求上下文
 */
@Injectable()
export class RegionGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    // 检查是否跳过区域检查
    const skipCheck = this.reflector.getAllAndOverride<boolean>(SKIP_REGION_CHECK, [
      context.getHandler(),
      context.getClass(),
    ]);

    if (skipCheck) {
      return true;
    }

    const request = context.switchToHttp().getRequest<Request>();
    const user = (request as any).user;

    // 如果没有用户（未认证），跳过区域检查
    if (!user) {
      return true;
    }

    // 从 Header 获取请求的区域
    const requestedRegion = this.getRequestedRegion(request);

    // 如果没有指定区域，使用用户默认区域
    if (!requestedRegion) {
      (request as any).currentRegion = user.defaultRegion || 'CN';
      return true;
    }

    // 验证区域是否有效
    if (!this.isValidRegion(requestedRegion)) {
      throw new ForbiddenException(`无效的区域: ${requestedRegion}`);
    }

    // 验证用户是否有权限访问该区域
    if (!this.canAccessRegion(user, requestedRegion)) {
      throw new ForbiddenException(`您没有权限访问 ${requestedRegion} 区域`);
    }

    // 将当前区域注入到请求上下文
    (request as any).currentRegion = requestedRegion;

    return true;
  }

  /**
   * 从请求中获取区域
   */
  private getRequestedRegion(request: Request): string | null {
    const region = request.headers[REGION_HEADER] as string;
    return region?.toUpperCase() || null;
  }

  /**
   * 验证区域是否有效
   */
  private isValidRegion(region: string): boolean {
    return SUPPORTED_REGIONS.includes(region as Region);
  }

  /**
   * 检查用户是否有权限访问指定区域
   */
  private canAccessRegion(user: any, region: string): boolean {
    const permissions = user.permissions || [];

    // 检查是否有全区域访问权限
    if (permissions.includes('region:*:access')) {
      return true;
    }

    // 检查是否有特定区域访问权限
    const regionPermission = `region:${region.toLowerCase()}:access`;
    if (permissions.includes(regionPermission)) {
      return true;
    }

    // 检查是否是用户的默认区域（默认区域总是可以访问）
    if (user.defaultRegion === region) {
      return true;
    }

    return false;
  }
}

/**
 * 跳过区域检查装饰器
 * 用于标记不需要区域检查的接口（如健康检查、登录等）
 */
import { SetMetadata } from '@nestjs/common';
export const SkipRegionCheck = () => SetMetadata(SKIP_REGION_CHECK, true);

