/**
 * 多因子评价服务类
 * 提供地块适宜性评价、批量分析等功能
 */

import {
  EvaluationFactor,
  SuitabilityResult,
  FactorWeight,
  BatchProgress,
  DEFAULT_FACTORS,
  WEIGHT_PRESETS,
  MOCK_FIELDS
} from './multiFactorTypes';

export class MultiFactorService {
  /**
   * 计算单个因子的得分
   */
  static calculateFactorScore(value: number, optimalRange: [number, number]): number {
    const [min, max] = optimalRange;
    const mid = (min + max) / 2;
    const range = max - min;

    // 如果在最佳范围内，得分较高
    if (value >= min && value <= max) {
      // 越接近中值得分越高 (85-100分)
      const deviation = Math.abs(value - mid);
      const deviationRatio = deviation / (range / 2);
      return Math.max(85, 100 - deviationRatio * 15);
    }

    // 如果在范围外，根据偏离程度降低分数
    const deviation = value < min ? min - value : value - max;
    const deviationRatio = deviation / range;

    // 偏离越大，分数越低 (最低20分)
    return Math.max(20, 85 - deviationRatio * 65);
  }

  /**
   * 计算综合评分（层次分析法AHP加权求和）
   */
  static calculateTotalScore(factors: EvaluationFactor[]): number {
    let totalScore = 0;
    for (const factor of factors) {
      totalScore += (factor.score * factor.weight) / 100;
    }
    return Math.round(totalScore);
  }

  /**
   * 根据总分确定适宜性等级
   */
  static getGrade(totalScore: number): '高度适宜' | '一般适宜' | '不适宜' {
    if (totalScore >= 80) return '高度适宜';
    if (totalScore >= 60) return '一般适宜';
    return '不适宜';
  }

  /**
   * 从空间分析服务读取地块因子数据
   */
  static fetchFieldFactorsFromSpatialService(fieldId: string, weights: FactorWeight[]): EvaluationFactor[] {
    // 模拟读取地块的土壤因子数据
    return [
      {
        id: 'ph',
        name: 'pH值',
        value: 6.0 + Math.random() * 2, // 6.0-8.0
        weight: weights.find(f => f.id === 'ph')?.weight || 20,
        unit: '',
        optimalRange: [6.5, 7.5],
        score: 0
      },
      {
        id: 'organic',
        name: '有机质含量',
        value: 15 + Math.random() * 20, // 15-35 g/kg
        weight: weights.find(f => f.id === 'organic')?.weight || 25,
        unit: 'g/kg',
        optimalRange: [20, 30],
        score: 0
      },
      {
        id: 'depth',
        name: '土层厚度',
        value: 30 + Math.random() * 70, // 30-100 cm
        weight: weights.find(f => f.id === 'depth')?.weight || 20,
        unit: 'cm',
        optimalRange: [50, 80],
        score: 0
      },
      {
        id: 'nitrogen',
        name: '全氮',
        value: 0.8 + Math.random() * 1.5, // 0.8-2.3 g/kg
        weight: weights.find(f => f.id === 'nitrogen')?.weight || 10,
        unit: 'g/kg',
        optimalRange: [1.0, 2.0],
        score: 0
      },
      {
        id: 'phosphorus',
        name: '全磷',
        value: 0.4 + Math.random() * 1.2, // 0.4-1.6 g/kg
        weight: weights.find(f => f.id === 'phosphorus')?.weight || 10,
        unit: 'g/kg',
        optimalRange: [0.6, 1.2],
        score: 0
      },
      {
        id: 'potassium',
        name: '全钾',
        value: 12 + Math.random() * 13, // 12-25 g/kg
        weight: weights.find(f => f.id === 'potassium')?.weight || 10,
        unit: 'g/kg',
        optimalRange: [15, 20],
        score: 0
      },
      {
        id: 'drainage',
        name: '排水性',
        value: 60 + Math.random() * 40, // 60-100分
        weight: weights.find(f => f.id === 'drainage')?.weight || 5,
        unit: '',
        optimalRange: [70, 90],
        score: 0
      },
    ];
  }

  /**
   * 生成地块适宜性评价结果
   */
  static generateEvaluationResult(fieldId: string, weights: FactorWeight[]): SuitabilityResult {
    const field = MOCK_FIELDS.find(f => f.id === fieldId);
    if (!field) {
      throw new Error(`Field ${fieldId} not found`);
    }

    // 从空间分析服务读取因子数据
    const factors = MultiFactorService.fetchFieldFactorsFromSpatialService(fieldId, weights);

    // 计算每个因子的得分
    const scoredFactors = factors.map(factor => ({
      ...factor,
      score: MultiFactorService.calculateFactorScore(factor.value, factor.optimalRange)
    }));

    // 计算综合得分（加权汇总）
    const totalScore = MultiFactorService.calculateTotalScore(scoredFactors);

    // 确定适宜性等级
    const grade = MultiFactorService.getGrade(totalScore);

    return {
      fieldId,
      fieldName: field.name,
      totalScore,
      grade,
      factors: scoredFactors,
      timestamp: new Date().toISOString(),
    };
  }

  /**
   * 批量分析所有地块
   */
  static async runBatchAnalysis(
    weights: FactorWeight[],
    onProgress?: (progress: BatchProgress) => void
  ): Promise<SuitabilityResult[]> {
    const totalFields = MOCK_FIELDS.length;
    const results: SuitabilityResult[] = [];
    let highSuitability = 0;
    let mediumSuitability = 0;
    let lowSuitability = 0;

    for (let i = 0; i < totalFields; i++) {
      const field = MOCK_FIELDS[i];

      // 模拟处理延迟
      await new Promise(resolve => setTimeout(resolve, 100));

      // 生成评价结果
      const result = MultiFactorService.generateEvaluationResult(field.id, weights);
      results.push(result);

      // 更新统计数据
      if (result.grade === '高度适宜') highSuitability++;
      else if (result.grade === '一般适宜') mediumSuitability++;
      else lowSuitability++;

      // 更新进度
      if (onProgress) {
        onProgress({
          total: totalFields,
          processed: i + 1,
          highSuitability,
          mediumSuitability,
          lowSuitability,
          currentField: field.name
        });
      }
    }

    return results;
  }

  /**
   * 验证权重总和
   */
  static validateWeights(weights: FactorWeight[]): { isValid: boolean; totalWeight: number } {
    const totalWeight = weights.reduce((sum, f) => sum + f.weight, 0);
    return {
      isValid: totalWeight === 100,
      totalWeight
    };
  }

  /**
   * 获取预设权重方案
   */
  static getWeightPreset(preset: 'grain' | 'economic' | 'default'): FactorWeight[] {
    switch (preset) {
      case 'grain':
        return [...WEIGHT_PRESETS.grain];
      case 'economic':
        return [...WEIGHT_PRESETS.economic];
      default:
        return [...DEFAULT_FACTORS];
    }
  }

  /**
   * 更新权重配置
   */
  static updateWeight(weights: FactorWeight[], factorId: string, newWeight: number): FactorWeight[] {
    return weights.map(f => f.id === factorId ? { ...f, weight: newWeight } : f);
  }

  /**
   * 重置权重到默认值
   */
  static resetWeights(): FactorWeight[] {
    return [...DEFAULT_FACTORS];
  }

  /**
   * 生成模拟评价数据（用于演示）
   */
  static generateMockEvaluationData(): SuitabilityResult[] {
    return [
      {
        fieldId: 'field-1',
        fieldName: '东区1号地',
        totalScore: 87,
        grade: '高度适宜',
        factors: [
          { id: 'ph', name: 'pH值', value: 6.5, weight: 20, unit: '', optimalRange: [6.0, 7.5], score: 95 },
          { id: 'organic', name: '有机质含量', value: 32, weight: 25, unit: 'g/kg', optimalRange: [25, 40], score: 90 },
          { id: 'depth', name: '土层厚度', value: 85, weight: 20, unit: 'cm', optimalRange: [60, 100], score: 88 },
          { id: 'nitrogen', name: '全氮', value: 1.8, weight: 10, unit: 'g/kg', optimalRange: [1.5, 2.5], score: 85 },
          { id: 'phosphorus', name: '全磷', value: 1.2, weight: 10, unit: 'g/kg', optimalRange: [1.0, 2.0], score: 80 },
          { id: 'potassium', name: '全钾', value: 18, weight: 10, unit: 'g/kg', optimalRange: [15, 25], score: 82 },
          { id: 'drainage', name: '排水性', value: 4, weight: 5, unit: '', optimalRange: [3, 5], score: 90 },
        ],
        timestamp: '2024-10-15 14:30',
      },
      {
        fieldId: 'field-2',
        fieldName: '西区2号地',
        totalScore: 72,
        grade: '一般适宜',
        factors: [
          { id: 'ph', name: 'pH值', value: 7.8, weight: 20, unit: '', optimalRange: [6.0, 7.5], score: 65 },
          { id: 'organic', name: '有机质含量', value: 22, weight: 25, unit: 'g/kg', optimalRange: [25, 40], score: 70 },
          { id: 'depth', name: '土层厚度', value: 55, weight: 20, unit: 'cm', optimalRange: [60, 100], score: 68 },
          { id: 'nitrogen', name: '全氮', value: 1.3, weight: 10, unit: 'g/kg', optimalRange: [1.5, 2.5], score: 72 },
          { id: 'phosphorus', name: '全磷', value: 0.9, weight: 10, unit: 'g/kg', optimalRange: [1.0, 2.0], score: 75 },
          { id: 'potassium', name: '全钾', value: 14, weight: 10, unit: 'g/kg', optimalRange: [15, 25], score: 78 },
          { id: 'drainage', name: '排水性', value: 3, weight: 5, unit: '', optimalRange: [3, 5], score: 85 },
        ],
        timestamp: '2024-10-15 14:28',
      },
      {
        fieldId: 'field-3',
        fieldName: '南区3号地',
        totalScore: 58,
        grade: '不适宜',
        factors: [
          { id: 'ph', name: 'pH值', value: 8.5, weight: 20, unit: '', optimalRange: [6.0, 7.5], score: 45 },
          { id: 'organic', name: '有机质含量', value: 15, weight: 25, unit: 'g/kg', optimalRange: [25, 40], score: 52 },
          { id: 'depth', name: '土层厚度', value: 42, weight: 20, unit: 'cm', optimalRange: [60, 100], score: 55 },
          { id: 'nitrogen', name: '全氮', value: 0.8, weight: 10, unit: 'g/kg', optimalRange: [1.5, 2.5], score: 60 },
          { id: 'phosphorus', name: '全磷', value: 0.6, weight: 10, unit: 'g/kg', optimalRange: [1.0, 2.0], score: 65 },
          { id: 'potassium', name: '全钾', value: 10, weight: 10, unit: 'g/kg', optimalRange: [15, 25], score: 58 },
          { id: 'drainage', name: '排水性', value: 2, weight: 5, unit: '', optimalRange: [3, 5], score: 70 },
        ],
        timestamp: '2024-10-15 14:25',
      },
    ];
  }

  /**
   * 生成更多模拟地块数据（用于批量分析演示）
   */
  static generateExtendedMockFields(): Array<{ id: string; name: string; code: string; area: number }> {
    const extendedFields = [...MOCK_FIELDS];

    // 生成更多模拟地块
    for (let i = 4; i <= 68; i++) {
      const zone = ['东区', '西区', '南区', '北区', '中心区'][Math.floor(Math.random() * 5)];
      const number = Math.floor(Math.random() * 20) + 1;
      const area = Math.round((Math.random() * 100 + 50) * 10) / 10;

      extendedFields.push({
        id: `field-${i}`,
        name: `${zone}${number}号地`,
        code: `DB${String(i).padStart(3, '0')}`,
        area
      });
    }

    return extendedFields;
  }
}