/**
 * 土壤质量评价服务类
 * 提供土壤质量分析、评价和改良建议功能
 */

import {
  SoilIndicator,
  SoilQualityEvaluation,
  SoilRecommendation,
  SoilQualityHistory,
  SoilAnalysisForm,
  FertilizerRecommendation,
  SOIL_INDICATORS,
  SOIL_QUALITY_GRADES,
  SOIL_TYPES,
  SOIL_TEXTURES,
  DRAINAGE_LEVELS
} from './soilTypes';

export class SoilQualityService {
  /**
   * 根据土壤分析表单数据生成土壤指标
   */
  static generateIndicators(formData: SoilAnalysisForm): SoilIndicator[] {
    const indicators: SoilIndicator[] = [];

    // 处理每个指标
    Object.entries(SOIL_INDICATORS).forEach(([key, config]) => {
      let value: number;

      switch (key) {
        case 'ph':
          value = formData.ph;
          break;
        case 'organicMatter':
          value = formData.organicMatter;
          break;
        case 'nitrogen':
          value = formData.nitrogen;
          break;
        case 'phosphorus':
          value = formData.phosphorus;
          break;
        case 'potassium':
          value = formData.potassium;
          break;
        case 'calcium':
          value = formData.calcium;
          break;
        case 'magnesium':
          value = formData.magnesium;
          break;
        case 'sulfur':
          value = formData.sulfur;
          break;
        case 'iron':
          value = formData.iron;
          break;
        case 'manganese':
          value = formData.manganese;
          break;
        case 'zinc':
          value = formData.zinc;
          break;
        case 'copper':
          value = formData.copper;
          break;
        case 'boron':
          value = formData.boron;
          break;
        default:
          return;
      }

      const score = this.calculateIndicatorScore(value, config.optimalRange);
      const status = this.getIndicatorStatus(score);

      indicators.push({
        id: config.id,
        name: config.name,
        value,
        unit: config.unit,
        optimalRange: config.optimalRange,
        score,
        status,
        weight: config.weight,
        description: config.description
      });
    });

    return indicators;
  }

  /**
   * 计算单个指标的得分
   */
  static calculateIndicatorScore(value: number, optimalRange: { min: number; max: number }): number {
    if (value >= optimalRange.min && value <= optimalRange.max) {
      // 在最佳范围内，满分
      return 100;
    }

    const midPoint = (optimalRange.min + optimalRange.max) / 2;
    const range = optimalRange.max - optimalRange.min;

    if (value < optimalRange.min) {
      // 低于最佳范围
      const deviation = optimalRange.min - value;
      if (deviation <= range * 0.5) {
        return 100 - (deviation / (range * 0.5)) * 30;
      } else {
        return Math.max(0, 70 - (deviation - range * 0.5) / range * 70);
      }
    } else {
      // 高于最佳范围
      const deviation = value - optimalRange.max;
      if (deviation <= range * 0.5) {
        return 100 - (deviation / (range * 0.5)) * 30;
      } else {
        return Math.max(0, 70 - (deviation - range * 0.5) / range * 70);
      }
    }
  }

  /**
   * 获取指标状态
   */
  static getIndicatorStatus(score: number): 'excellent' | 'good' | 'moderate' | 'poor' | 'very_poor' {
    if (score >= 90) return 'excellent';
    if (score >= 80) return 'good';
    if (score >= 70) return 'moderate';
    if (score >= 60) return 'poor';
    return 'very_poor';
  }

  /**
   * 计算土壤质量总体评分
   */
  static calculateOverallScore(indicators: SoilIndicator[]): number {
    const weightedSum = indicators.reduce((sum, indicator) => {
      return sum + (indicator.score * indicator.weight);
    }, 0);

    return Math.round(weightedSum);
  }

  /**
   * 获取土壤质量等级
   */
  static getSoilQualityGrade(score: number): 'A' | 'B' | 'C' | 'D' | 'E' {
    for (const [grade, config] of Object.entries(SOIL_QUALITY_GRADES)) {
      if (score >= config.min && score <= config.max) {
        return grade as 'A' | 'B' | 'C' | 'D' | 'E';
      }
    }
    return 'E';
  }

  /**
   * 生成土壤质量评价
   */
  static generateEvaluation(formData: SoilAnalysisForm): SoilQualityEvaluation {
    const indicators = this.generateIndicators(formData);
    const overallScore = this.calculateOverallScore(indicators);
    const overallGrade = this.getSoilQualityGrade(overallScore);
    const recommendations = this.generateRecommendations(indicators, formData);

    return {
      id: `eval-${Date.now()}`,
      fieldId: formData.fieldId,
      fieldName: this.getFieldName(formData.fieldId),
      date: formData.sampleDate,
      location: this.getFieldLocation(formData.fieldId),
      indicators,
      overallScore,
      overallGrade,
      soilType: this.determineSoilType(formData.soilTexture),
      texture: formData.soilTexture,
      drainage: formData.drainage as any,
      fertility: this.determineFertility(overallScore),
      recommendations,
      evaluationNotes: formData.notes || '',
      evaluator: '系统自动评价',
      nextEvaluationDate: this.calculateNextEvaluationDate(formData.sampleDate)
    };
  }

  /**
   * 生成改良建议
   */
  static generateRecommendations(indicators: SoilIndicator[], formData: SoilAnalysisForm): SoilRecommendation[] {
    const recommendations: SoilRecommendation[] = [];

    // 分析pH值
    const phIndicator = indicators.find(ind => ind.id === 'ph');
    if (phIndicator && (phIndicator.status === 'poor' || phIndicator.status === 'very_poor')) {
      if (phIndicator.value < 6.0) {
        recommendations.push({
          category: 'ph_adjustment',
          priority: 'high',
          title: '土壤酸化改良',
          description: '土壤偏酸性，需要进行酸化改良以提高pH值',
          actionItems: [
            '施用石灰，每亩施用量100-200公斤',
            '增施有机肥，改善土壤缓冲能力',
            '选择耐酸性作物进行轮作',
            '减少酸性肥料的使用'
          ],
          expectedImprovement: 15,
          timeframe: '3-6个月',
          estimatedCost: 200,
          costUnit: 'yuan_per_mu'
        });
      } else if (phIndicator.value > 7.5) {
        recommendations.push({
          category: 'ph_adjustment',
          priority: 'high',
          title: '土壤碱化改良',
          description: '土壤偏碱性，需要进行碱化改良以降低pH值',
          actionItems: [
            '施用硫磺或硫酸亚铁，每亩施用量20-50公斤',
            '增施酸性有机肥（如松针堆肥）',
            '种植绿肥作物，如三叶草、苜蓿',
            '减少碱性肥料的使用'
          ],
          expectedImprovement: 15,
          timeframe: '6-12个月',
          estimatedCost: 300,
          costUnit: 'yuan_per_mu'
        });
      }
    }

    // 分析有机质
    const omIndicator = indicators.find(ind => ind.id === 'organicMatter');
    if (omIndicator && omIndicator.status !== 'excellent') {
      recommendations.push({
        category: 'organic_matter',
        priority: omIndicator.status === 'very_poor' ? 'high' : 'medium',
        title: '有机质提升',
        description: '土壤有机质含量偏低，需要增施有机肥',
        actionItems: [
          '施用腐熟农家肥，每亩2000-3000公斤',
          '种植绿肥作物并翻压还田',
          '秸秆还田，增加土壤有机质',
          '使用生物有机肥，改善土壤微生物环境'
        ],
        expectedImprovement: 20,
        timeframe: '6-12个月',
        estimatedCost: 500,
        costUnit: 'yuan_per_mu'
      });
    }

    // 分析氮磷钾
    const npkIndicators = indicators.filter(ind => ['nitrogen', 'phosphorus', 'potassium'].includes(ind.id));
    const deficientNPK = npkIndicators.filter(ind => ind.status === 'poor' || ind.status === 'very_poor');

    if (deficientNPK.length > 0) {
      const fertilizerRec = this.generateFertilizerRecommendation(deficientNPK);
      recommendations.push({
        category: 'fertilizer',
        priority: 'high',
        title: '营养元素补充',
        description: `土壤缺乏${deficientNPK.map(ind => ind.name).join('、')}，需要针对性施肥`,
        actionItems: fertilizerRec.actionItems,
        expectedImprovement: 25,
        timeframe: '1-3个月',
        estimatedCost: fertilizerRec.estimatedCost,
        costUnit: 'yuan_per_mu'
      });
    }

    // 分析微量元素
    const microIndicators = indicators.filter(ind =>
      ['iron', 'manganese', 'zinc', 'copper', 'boron'].includes(ind.id) &&
      (ind.status === 'poor' || ind.status === 'very_poor')
    );

    if (microIndicators.length > 0) {
      recommendations.push({
        category: 'fertilizer',
        priority: 'medium',
        title: '微量元素补充',
        description: `土壤缺乏${microIndicators.map(ind => ind.name).join('、')}等微量元素`,
        actionItems: [
          '施用复合微量元素肥料',
          '叶面喷施微量元素溶液',
          '增施有机肥，提高微量元素有效性',
          '调节土壤pH值，改善微量元素吸收'
        ],
        expectedImprovement: 10,
        timeframe: '1-2个月',
        estimatedCost: 150,
        costUnit: 'yuan_per_mu'
      });
    }

    // 排水改良建议
    if (formData.drainage === 'poor' || formData.drainage === 'moderate') {
      recommendations.push({
        category: 'drainage',
        priority: formData.drainage === 'poor' ? 'high' : 'medium',
        title: '排水系统改良',
        description: '土壤排水条件较差，需要改良排水系统',
        actionItems: [
          '开挖排水沟，改善地表排水',
          '深耕土壤，打破犁底层',
          '增施有机肥，改善土壤结构',
          '种植深根系作物，改良土壤通透性'
        ],
        expectedImprovement: 15,
        timeframe: '3-6个月',
        estimatedCost: 800,
        costUnit: 'yuan_per_mu'
      });
    }

    return recommendations.sort((a, b) => {
      const priorityOrder = { high: 3, medium: 2, low: 1 };
      return priorityOrder[b.priority] - priorityOrder[a.priority];
    });
  }

  /**
   * 生成施肥建议
   */
  private static generateFertilizerRecommendation(deficientIndicators: SoilIndicator[]): {
    actionItems: string[];
    estimatedCost: number;
  } {
    const actionItems: string[] = [];
    let estimatedCost = 0;

    deficientIndicators.forEach(indicator => {
      switch (indicator.id) {
        case 'nitrogen':
          actionItems.push('施用尿素，每亩20-30公斤');
          actionItems.push('或施用复合肥（15-15-15），每亩40-50公斤');
          estimatedCost += 120;
          break;
        case 'phosphorus':
          actionItems.push('施用过磷酸钙，每亩30-40公斤');
          actionItems.push('或施用磷酸二铵，每亩15-20公斤');
          estimatedCost += 100;
          break;
        case 'potassium':
          actionItems.push('施用氯化钾，每亩10-15公斤');
          actionItems.push('或施用硫酸钾，每亩12-18公斤');
          estimatedCost += 80;
          break;
      }
    });

    return { actionItems, estimatedCost };
  }

  /**
   * 确定土壤肥力等级
   */
  static determineFertility(score: number): 'high' | 'medium' | 'low' {
    if (score >= 80) return 'high';
    if (score >= 60) return 'medium';
    return 'low';
  }

  /**
   * 确定土壤类型
   */
  static determineSoilType(texture: string): string {
    const soilType = SOIL_TYPES.find(type => type.id === texture);
    return soilType ? soilType.name : '未知';
  }

  /**
   * 获取地块名称
   */
  private static getFieldName(fieldId: string): string {
    const mockFields = {
      'field-1': '东区1号地',
      'field-2': '西区2号地',
      'field-3': '南区3号地'
    };
    return mockFields[fieldId as keyof typeof mockFields] || '未知地块';
  }

  /**
   * 获取地块位置
   */
  private static getFieldLocation(fieldId: string): string {
    const mockLocations = {
      'field-1': '东区A区',
      'field-2': '西区B区',
      'field-3': '南区C区'
    };
    return mockLocations[fieldId as keyof typeof mockLocations] || '未知位置';
  }

  /**
   * 计算下次评价日期
   */
  private static calculateNextEvaluationDate(currentDate: string): string {
    const date = new Date(currentDate);
    date.setFullYear(date.getFullYear() + 1);
    return date.toISOString().split('T')[0];
  }

  /**
   * 获取历史记录数据
   */
  static getHistoricalData(fieldId: string): SoilQualityHistory[] {
    // 模拟历史数据
    const mockHistory: SoilQualityHistory[] = [
      {
        date: '2024-01-15',
        overallScore: 75,
        indicatorChanges: [],
        evaluation: {
          id: 'eval-2024-01',
          fieldId,
          fieldName: this.getFieldName(fieldId),
          date: '2024-01-15',
          location: this.getFieldLocation(fieldId),
          indicators: [],
          overallScore: 75,
          overallGrade: 'C',
          soilType: '壤土',
          texture: 'medium',
          drainage: 'good',
          fertility: 'medium',
          recommendations: [],
          evaluationNotes: '春季施肥前取样分析',
          evaluator: '技术员张三',
          nextEvaluationDate: '2025-01-15'
        }
      },
      {
        date: '2023-07-20',
        overallScore: 72,
        indicatorChanges: [],
        evaluation: {
          id: 'eval-2023-07',
          fieldId,
          fieldName: this.getFieldName(fieldId),
          date: '2023-07-20',
          location: this.getFieldLocation(fieldId),
          indicators: [],
          overallScore: 72,
          overallGrade: 'C',
          soilType: '壤土',
          texture: 'medium',
          drainage: 'good',
          fertility: 'medium',
          recommendations: [],
          evaluationNotes: '夏季作物生长期取样',
          evaluator: '技术员李四',
          nextEvaluationDate: '2024-07-20'
        }
      },
      {
        date: '2023-01-10',
        overallScore: 68,
        indicatorChanges: [],
        evaluation: {
          id: 'eval-2023-01',
          fieldId,
          fieldName: this.getFieldName(fieldId),
          date: '2023-01-10',
          location: this.getFieldLocation(fieldId),
          indicators: [],
          overallScore: 68,
          overallGrade: 'D',
          soilType: '壤土',
          texture: 'medium',
          drainage: 'moderate',
          fertility: 'low',
          recommendations: [],
          evaluationNotes: '年初土壤基础检测',
          evaluator: '技术员王五',
          nextEvaluationDate: '2024-01-10'
        }
      }
    ];

    return mockHistory;
  }

  /**
   * 分析指标变化趋势
   */
  static analyzeTrend(historicalData: SoilQualityHistory[]): {
    trend: 'improving' | 'stable' | 'declining';
    changeRate: number;
    description: string;
  } {
    if (historicalData.length < 2) {
      return {
        trend: 'stable',
        changeRate: 0,
        description: '数据不足，无法分析趋势'
      };
    }

    const latest = historicalData[0];
    const previous = historicalData[1];
    const change = latest.overallScore - previous.overallScore;

    let trend: 'improving' | 'stable' | 'declining';
    let description: string;

    if (Math.abs(change) < 3) {
      trend = 'stable';
      description = '土壤质量保持稳定';
    } else if (change > 0) {
      trend = 'improving';
      description = `土壤质量正在改善，提升了${change}分`;
    } else {
      trend = 'declining';
      description = `土壤质量有所下降，降低了${Math.abs(change)}分`;
    }

    return {
      trend,
      changeRate: change,
      description
    };
  }
}

// 工具函数
export const formatSoilScore = (score: number): string => {
  return `${score}分`;
};

export const getSoilGradeColor = (grade: string): string => {
  const gradeConfig = SOIL_QUALITY_GRADES[grade as keyof typeof SOIL_QUALITY_GRADES];
  return gradeConfig?.color || '#6b7280';
};

export const getIndicatorStatusColor = (status: string): string => {
  const colorMap = {
    excellent: '#22c55e',
    good: '#84cc16',
    moderate: '#eab308',
    poor: '#f97316',
    very_poor: '#ef4444'
  };
  return colorMap[status as keyof typeof colorMap] || '#6b7280';
};

export const formatDate = (dateString: string): string => {
  const date = new Date(dateString);
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  });
};