/**
 * 环境端口策略配置
 * 类似租户识别系统的环境优先级策略
 */

import type { PortStrategy } from './port-manager';

// 环境类型
export type Environment = 'development' | 'test' | 'staging' | 'production';

// 端口策略优先级
export interface PortPriority {
  environment: Environment;
  priority: number; // 数字越小优先级越高
  description: string;
}

// 环境端口策略配置
export interface EnvironmentPortStrategy extends PortStrategy {
  environment: Environment;
  priority: number;
  autoDetect: boolean;
  fallbackStrategy?: EnvironmentPortStrategy;
  restrictions: {
    allowedHosts: string[];
    blockedPorts: number[];
    requireHttps: boolean;
  };
}

// 端口分配模式
export enum PortAllocationMode {
  TENANT_BASED = 'tenant-based',     // 基于租户分配
  SEQUENTIAL = 'sequential',         // 顺序分配
  RANDOM = 'random',                // 随机分配
  HASH_BASED = 'hash-based'         // 基于哈希分配
}

// 环境检测器
export class EnvironmentDetector {
  /**
   * 检测当前环境
   */
  static detectEnvironment(): Environment {
    // 1. 检查环境变量
    const nodeEnv = process.env.NODE_ENV;
    if (nodeEnv) {
      switch (nodeEnv.toLowerCase()) {
        case 'development':
        case 'dev':
          return 'development';
        case 'test':
        case 'testing':
          return 'test';
        case 'staging':
        case 'stage':
          return 'staging';
        case 'production':
        case 'prod':
          return 'production';
      }
    }

    // 2. 检查域名
    const hostname = window.location.hostname;
    if (hostname.includes('localhost') || hostname.includes('127.0.0.1')) {
      return 'development';
    }
    if (hostname.includes('test') || hostname.includes('staging')) {
      return 'test';
    }
    if (hostname.includes('prod') || hostname.includes('www')) {
      return 'production';
    }

    // 3. 检查端口
    const port = window.location.port;
    if (port && parseInt(port) < 4000) {
      return 'development';
    }

    // 默认返回开发环境
    return 'development';
  }

  /**
   * 获取环境建议
   */
  static getEnvironmentRecommendation(): {
    detected: Environment;
    confidence: number;
    reasons: string[];
    suggestions: string[];
  } {
    const reasons: string[] = [];
    const suggestions: string[] = [];
    let confidence = 0;

    const nodeEnv = process.env.NODE_ENV;
    const hostname = window.location.hostname;
    const port = window.location.port;
    const protocol = window.location.protocol;

    // 分析环境变量
    if (nodeEnv) {
      reasons.push(`NODE_ENV: ${nodeEnv}`);
      confidence += 40;
    } else {
      suggestions.push('建议设置 NODE_ENV 环境变量');
    }

    // 分析域名
    if (hostname.includes('localhost')) {
      reasons.push('域名包含 localhost');
      confidence += 30;
    } else if (hostname.includes('test')) {
      reasons.push('域名包含 test');
      confidence += 25;
    } else if (hostname.includes('prod')) {
      reasons.push('域名包含 prod');
      confidence += 35;
    }

    // 分析协议
    if (protocol === 'https:') {
      reasons.push('使用 HTTPS 协议');
      confidence += 10;
    } else {
      suggestions.push('生产环境建议使用 HTTPS');
    }

    // 分析端口
    if (port) {
      const portNum = parseInt(port);
      if (portNum >= 3000 && portNum < 4000) {
        reasons.push('使用开发端口范围');
        confidence += 15;
      }
    }

    return {
      detected: this.detectEnvironment(),
      confidence: Math.min(confidence, 100),
      reasons,
      suggestions
    };
  }
}

// 端口策略管理器
export class PortStrategyManager {
  private strategies: Map<Environment, EnvironmentPortStrategy>;
  private currentEnvironment: Environment;

  constructor() {
    this.currentEnvironment = EnvironmentDetector.detectEnvironment();
    this.strategies = new Map();
    this.initializeDefaultStrategies();
  }

  /**
   * 初始化默认策略
   */
  private initializeDefaultStrategies(): void {
    // 开发环境策略
    this.strategies.set('development', {
      environment: 'development',
      priority: 1,
      basePort: 3000,
      portRange: [3000, 3999],
      tenantOffset: 10,
      environmentOffset: 0,
      maxRetries: 50,
      autoDetect: true,
      restrictions: {
        allowedHosts: ['localhost', '127.0.0.1', '0.0.0.0'],
        blockedPorts: [],
        requireHttps: false
      }
    });

    // 测试环境策略
    this.strategies.set('test', {
      environment: 'test',
      priority: 2,
      basePort: 4000,
      portRange: [4000, 4999],
      tenantOffset: 5,
      environmentOffset: 1000,
      maxRetries: 30,
      autoDetect: true,
      restrictions: {
        allowedHosts: ['localhost', '127.0.0.1', 'test.local'],
        blockedPorts: [4444, 4567], // 避免与其他测试工具冲突
        requireHttps: false
      }
    });

    // 预发布环境策略
    this.strategies.set('staging', {
      environment: 'staging',
      priority: 3,
      basePort: 5000,
      portRange: [5000, 5999],
      tenantOffset: 3,
      environmentOffset: 2000,
      maxRetries: 20,
      autoDetect: true,
      restrictions: {
        allowedHosts: ['staging.local', 'stage.example.com'],
        blockedPorts: [],
        requireHttps: true
      }
    });

    // 生产环境策略
    this.strategies.set('production', {
      environment: 'production',
      priority: 4,
      basePort: 8080,
      portRange: [8080, 8999],
      tenantOffset: 1,
      environmentOffset: 5000,
      maxRetries: 10,
      autoDetect: false, // 生产环境不自动检测
      restrictions: {
        allowedHosts: ['0.0.0.0'], // 生产环境通常绑定所有接口
        blockedPorts: [8080, 8443], // 避免与常用服务冲突
        requireHttps: true
      }
    });
  }

  /**
   * 获取当前环境策略
   */
  getCurrentStrategy(): EnvironmentPortStrategy {
    const strategy = this.strategies.get(this.currentEnvironment);
    if (!strategy) {
      console.warn(`未找到环境 ${this.currentEnvironment} 的策略，使用开发环境策略`);
      return this.strategies.get('development')!;
    }
    return strategy;
  }

  /**
   * 获取指定环境策略
   */
  getStrategy(environment: Environment): EnvironmentPortStrategy | undefined {
    return this.strategies.get(environment);
  }

  /**
   * 设置环境策略
   */
  setStrategy(environment: Environment, strategy: EnvironmentPortStrategy): void {
    this.strategies.set(environment, strategy);
    console.log(`✅ 已更新 ${environment} 环境的端口策略`);
  }

  /**
   * 获取推荐策略（基于环境优先级）
   */
  getRecommendedStrategy(): {
    primary: EnvironmentPortStrategy;
    fallback: EnvironmentPortStrategy[];
    reasoning: string[];
  } {
    const current = this.getCurrentStrategy();
    const reasoning: string[] = [];
    const fallback: EnvironmentPortStrategy[] = [];

    reasoning.push(`当前环境: ${this.currentEnvironment}`);
    reasoning.push(`优先级: ${current.priority}`);

    // 获取备选策略（按优先级排序）
    const allStrategies = Array.from(this.strategies.values())
      .filter(s => s.environment !== this.currentEnvironment)
      .sort((a, b) => a.priority - b.priority);

    fallback.push(...allStrategies);

    // 环境特定的推理
    switch (this.currentEnvironment) {
      case 'development':
        reasoning.push('开发环境优先考虑端口可用性和调试便利性');
        break;
      case 'test':
        reasoning.push('测试环境需要隔离性和可重复性');
        break;
      case 'staging':
        reasoning.push('预发布环境模拟生产环境配置');
        break;
      case 'production':
        reasoning.push('生产环境优先考虑安全性和稳定性');
        break;
    }

    return { primary: current, fallback, reasoning };
  }

  /**
   * 验证端口策略
   */
  validateStrategy(strategy: EnvironmentPortStrategy): {
    isValid: boolean;
    errors: string[];
    warnings: string[];
  } {
    const errors: string[] = [];
    const warnings: string[] = [];

    // 检查端口范围
    if (strategy.portRange[0] >= strategy.portRange[1]) {
      errors.push('端口范围无效：起始端口必须小于结束端口');
    }

    if (strategy.portRange[0] < 1024 && strategy.environment === 'production') {
      warnings.push('生产环境使用系统端口（<1024）可能需要管理员权限');
    }

    // 检查基础端口
    if (strategy.basePort < strategy.portRange[0] || strategy.basePort > strategy.portRange[1]) {
      errors.push('基础端口不在允许的端口范围内');
    }

    // 检查租户偏移
    if (strategy.tenantOffset <= 0) {
      warnings.push('租户偏移为0可能导致端口冲突');
    }

    // 检查环境特定规则
    if (strategy.environment === 'production' && !strategy.restrictions.requireHttps) {
      warnings.push('生产环境建议启用 HTTPS');
    }

    if (strategy.environment === 'development' && strategy.restrictions.requireHttps) {
      warnings.push('开发环境启用 HTTPS 可能增加配置复杂度');
    }

    return {
      isValid: errors.length === 0,
      errors,
      warnings
    };
  }

  /**
   * 获取环境统计信息
   */
  getEnvironmentStats(): {
    current: Environment;
    available: Environment[];
    strategies: Array<{
      environment: Environment;
      priority: number;
      portRange: [number, number];
      isValid: boolean;
    }>;
  } {
    const strategies = Array.from(this.strategies.entries()).map(([env, strategy]) => ({
      environment: env,
      priority: strategy.priority,
      portRange: strategy.portRange,
      isValid: this.validateStrategy(strategy).isValid
    }));

    return {
      current: this.currentEnvironment,
      available: Array.from(this.strategies.keys()),
      strategies: strategies.sort((a, b) => a.priority - b.priority)
    };
  }

  /**
   * 切换环境
   */
  switchEnvironment(environment: Environment): boolean {
    if (!this.strategies.has(environment)) {
      console.error(`环境 ${environment} 不存在`);
      return false;
    }

    this.currentEnvironment = environment;
    console.log(`🔄 已切换到 ${environment} 环境`);
    return true;
  }
}

// 导出默认实例
export const portStrategyManager = new PortStrategyManager();

// 导出环境优先级配置
export const ENVIRONMENT_PRIORITIES: PortPriority[] = [
  {
    environment: 'development',
    priority: 1,
    description: '开发环境 - 最高优先级，注重便利性'
  },
  {
    environment: 'test',
    priority: 2,
    description: '测试环境 - 高优先级，注重隔离性'
  },
  {
    environment: 'staging',
    priority: 3,
    description: '预发布环境 - 中等优先级，模拟生产'
  },
  {
    environment: 'production',
    priority: 4,
    description: '生产环境 - 最低优先级，注重安全性'
  }
];
