package common

import (
	"math"
	"strconv"
)

//计算空气质量转换等级
func CalculateAirQuality(d float64) string {
	//d, err := strconv.ParseFloat(airQuality, 64)
	//if err != nil {
	//	panic(err.Error())
	//}
	val := "-"
	if d <= 50 {
		val = "优"
	} else if d > 50 && d <= 100 {
		val = "良"
	} else if d > 100 && d <= 150 {
		val = "轻度污染"
	} else if d > 150 && d <= 200 {
		val = "中度污染"
	} else if d > 200 && d < 300 {
		val = "重度污染"
	} else if d > 300 {
		val = "严重污染"
	}
	return val
}

/**
 * 特别注意此方法 不能在这里使用
 * 根据提供污染物的各项指标，对AQI进行计算
 *
 * @param pmtw PM2.5
 * @param pmte PM10
 * @param co   一氧化碳浓度
 * @param no2  二氧化氮浓度
 * @param o3   臭氧浓度
 * @param so2  二氧化硫浓度
 * @return
 */
//func CountAqi(pmtw float64, pmte float64, co float64, no2 float64, o3 float64, so2 float64) *dao.AqiData {
//	var pmtwIaqi float64 = getPm25IAQI(pmtw)
//	var pmteIaqi float64 = getPm10IAQI(pmte)
//	var coIaqi float64 = getCoIAQI(co)
//	var no2Iaqi float64 = getNo2IAQI(no2)
//	var o3Iaqi float64 = getO3OneHourIAQI(o3)
//	var so2Iaqi float64 = getSo2IAQI(so2)
//	var aList []dao.AqiData
//	//// 初始化对象数组
//	if pmtwIaqi != 0 {
//		aList = append(aList, dao.AqiData{Name: "PM2.5", Aqi: pmtwIaqi})
//	}
//	if pmteIaqi != 0 {
//		aList = append(aList, dao.AqiData{Name: "PM10", Aqi: pmteIaqi})
//	}
//	if coIaqi != 0 {
//		aList = append(aList, dao.AqiData{Name: "CO", Aqi: coIaqi})
//	}
//	if no2Iaqi != 0 {
//		aList = append(aList, dao.AqiData{Name: "NO2", Aqi: no2Iaqi})
//	}
//	if o3Iaqi != 0 {
//		aList = append(aList, dao.AqiData{Name: "O3", Aqi: o3Iaqi})
//	}
//	if so2Iaqi != 0 {
//		aList = append(aList, dao.AqiData{Name: "SO2", Aqi: so2Iaqi})
//	}
//	sort.Slice(aList, func(i, j int) bool {
//		f := aList[i].Aqi - aList[j].Aqi
//		if f > 0 {
//			return true
//		}
//		return false
//	})
//	var aqi dao.AqiData
//	if len(aList) > 0 {
//		aqi = aList[len(aList)-1]
//	} else {
//		aqi = dao.AqiData{"PM10", 0.0}
//	}
//	return &aqi
//}

func getCoIAQI(co float64) float64 {
	if co > 0 {
		return countPerIaqi(co, 3)
	}
	return 0
}

func getNo2IAQI(no2 float64) float64 {
	if no2 > 0 {
		return countPerIaqi(no2, 4)
	}
	return 0
}

func getO3OneHourIAQI(o3One float64) float64 {
	if o3One > 0 {
		return countPerIaqi(o3One, 5)
	}
	return 0
}

func getSo2IAQI(so2 float64) float64 {
	if so2 > 0 {
		return countPerIaqi(so2, 6)
	}
	return 0
}

/**
 * 计算风向角度，转换成中文方向
 *
 * @param windDirection
 * @return
 */
func CalculateDirection(windDirection string) string {
	d, _ := strconv.ParseFloat(windDirection, 64)
	val := "-"
	if d > 337.5 || d < 22.5 {
		//Namezh: "北", Name: "N", Center: 0, DirectionA: 337.5, DirectionB: 22.5
		val = "北"
	} else if d > 22.5 && d < 67.5 {
		//Direction{Namezh: "东北", Name: "NE", Center: 45, DirectionA: 22.5, DirectionB: 67.5}
		val = "东北"
	} else if d > 67.5 && d < 112.5 {
		//Namezh:"东", Name:"E", Center:90, DirectionA:67.5, DirectionB:112.5
		val = "东"
	} else if d > 112.5 && d < 157.5 {
		//Namezh: "东南", Name: "SN", Center: 135, DirectionA: 112.5, DirectionB: 157.5
		val = "东南"
	} else if d > 157.5 && d < 202.5 {
		//Namezh: "南", Name: "S", Center: 180, DirectionA: 157.5, DirectionB: 202.5
		val = "南"
	} else if d > 202.5 && d < 247.5 {
		//Namezh: "西南", Name: "SW", Center: 225, DirectionA: 202.5, DirectionB: 247.5
		val = "西南"
	} else if d > 247.5 && d < 292.5 {
		//Namezh: "西", Name: "W", Center: 270, DirectionA: 247.5, DirectionB: 292.5
		val = "西"
	} else if d > 292.5 && d < 337.5 {
		//Namezh: "西北", Name: "NW", Center: 315, DirectionA: 292.5, DirectionB: 337.5
		val = "西北"
	}
	return val
}

/**
 * 计算风速等级
 *
 * @param speed
 * @return
 */
func CalculateSpeed(speed string) string {
	//风力等级范围
	d, _ := strconv.ParseFloat(speed, 64)
	val := "-"
	if d >= 0.0 && d <= 0.2 {
		val = "无风"
	} else if d >= 0.3 && d <= 1.5 {
		val = "软风(一级)"
	} else if d >= 1.6 && d <= 3.3 {
		val = "轻风(二级)"
	} else if d >= 3.4 && d <= 5.4 {
		val = "微风(三级)"
	} else if d >= 5.5 && d <= 7.9 {
		val = "和风(四级)"
	} else if d >= 8.0 && d <= 10.7 {
		val = "清劲风(五级)"
	} else if d >= 10.8 && d <= 13.8 {
		val = "强风(六级)"
	} else if d >= 13.9 && d <= 17.1 {
		val = "疾风(七级)"
	} else if d >= 17.2 && d <= 20.7 {
		val = "大风(八级)"
	} else if d >= 20.8 && d <= 24.4 {
		val = "烈风(九级)"
	} else if d >= 24.5 && d <= 28.4 {
		val = "狂风(十级)"
	} else if d >= 28.5 && d <= 32.6 {
		val = "暴风(11级)"
	} else if d > 32.6 {
		val = "台风(12级)"
	}
	return val
}

func getPollutionDegree(aqi float64) int {
	var pollutionDegree int = 1
	if aqi <= 50 {
		pollutionDegree = 1
	} else if aqi > 50 && aqi <= 100 {
		pollutionDegree = 2
	} else if aqi > 100 && aqi <= 150 {
		pollutionDegree = 3
	} else if aqi > 150 && aqi <= 200 {
		pollutionDegree = 4
	} else if aqi > 200 && aqi <= 250 {
		pollutionDegree = 5
	} else if aqi > 250 && aqi <= 300 {
		pollutionDegree = 6
	} else if aqi > 300 {
		pollutionDegree = 7
	}
	return pollutionDegree
}

func getDegree(pollutionDegree int) string {
	if pollutionDegree == 1 {
		return "优"
	} else if pollutionDegree == 2 {
		return "良"
	} else if pollutionDegree == 3 {
		return "轻微污染"
	} else if pollutionDegree == 4 {
		return "轻度污染"
	} else if pollutionDegree == 5 {
		return "中度污染"
	} else if pollutionDegree == 6 {
		return "中度重污染"
	} else if pollutionDegree == 7 {
		return "重度污染"
	}
	return "良"
}

func countPerIaqi(cp float64, r int) float64 {
	var bph float64 = 0   // 与 cp相近的污染物浓度限值的高位值
	var bpl float64 = 0   // 与 cp相近的污染物浓度限值的低位值
	var iaqih float64 = 0 // 与 bph对应的空气质量分指数
	var iaqil float64 = 0 // 与 bpl对应的空气质量分指数
	var iaqip float64 = 0 // 当前污染物项目P的空气质量分指数

	// 空气质量分指数及对应的污染物项目浓度限值
	var aqiArr [3][8]float64 = [3][8]float64{{0, 50, 100, 150, 200, 300, 400, 500}, {0, 50, 150, 250, 350, 420, 500, 600}, {0, 35, 75, 115, 150, 250, 350, 500}}

	var min float64 = aqiArr[r][0]
	var index int = len(aqiArr[r]) - 1
	var max float64 = aqiArr[r][index]
	if cp <= min || cp >= max {
		return 0.0
	} else {
		// 对每种污染物的bph、bpl、iaqih、iaqil进行赋值
		for i := r; i < (r + 1); i++ {
			for j := 0; j < len(aqiArr[0]); j++ {
				if cp < aqiArr[i][j] {
					bph = aqiArr[i][j]
					bpl = aqiArr[i][j-1]
					iaqih = aqiArr[0][j]
					iaqil = aqiArr[0][j-1]
					break
				}
			}
		}
		// 计算污染物项目P的空气质量分指数
		iaqip = (iaqih-iaqil)/(bph-bpl)*(cp-bpl) + iaqil
		return iaqip
	}
}

func getPm10IAQI(pmte float64) float64 {
	if pmte > 0 {
		return countPerIaqi(pmte, 1)
	}
	return 0
}

func getPm25IAQI(pmtw float64) float64 {
	if pmtw > 0 {
		return countPerIaqi(pmtw, 2)
	}
	return 0
}

func CountAqi(pmtw, pmte float64) float64 {
	var pmtwIaqi float64 = getPm25IAQI(pmtw)
	var pmteIaqi float64 = getPm10IAQI(pmte)
	return math.Max(pmteIaqi, pmtwIaqi)
}

func GetDegree(pmtw, pmte float64) string {
	return getDegree(getPollutionDegree(CountAqi(pmtw, pmte)))
}

func GetAqiAndDegree(pmtw, pmte float64) (float64, string) {
	aqi := CountAqi(pmtw, pmte)
	degree := getDegree(getPollutionDegree(aqi))
	return aqi, degree
}
