package service

import (
	"fmt"
	"log"
	"math"
	"strconv"
	"time"
	"ydMonitoring/databases"
)

type Devices struct {
	Tsn string // 设备编号
}

type DeviceSensors struct {
	Tsn   string // 设备编号
	TId   string // 设备ID
	TPid  string // PID
	TName string // 设备名称
}

type DeviceDatas struct {
	T_T    float64 // 温度
	T_rh   float64 // 湿度
	T_Time string  // 数据上传时间
}

// Forewarn 查询所有数据间隔时间
func Forewarn(devices []Device) {
	message := make([]string, 0)

	// 查询设备信息
	sqllist := make([]string, 0)
	for _, v := range devices {
		sql := fmt.Sprintf("select t_sn,t_id,t_pid,t_name from device_sensor where t_sn = %s", v.Tsn)
		sqllist = append(sqllist, sql)
	}
	deviceSensor := make([]DeviceSensors, 0)
	for _, sql := range sqllist {
		rows, err := databases.Db.Query(sql)
		if err != nil {
			log.Println("查询设备信息失败:", err)
			continue
		}
		defer rows.Close()
		for rows.Next() {
			var sn, t_id, t_pid, t_name string
			err := rows.Scan(&sn, &t_id, &t_pid, &t_name)
			if err != nil {
				log.Println("扫描设备信息失败:", err)
				continue
			}
			deviceSensor = append(deviceSensor, DeviceSensors{sn, t_id, t_pid, t_name})
		}
	}

	// 获取设备参数
	for _, sensor := range deviceSensor {
		var t_save_t string    // 保存间隔时间
		var t_warn string      // 报警间隔时间
		var t_tlower float64   // 低温下限
		var t_tupper float64   // 高温上限
		var t_r_hlower float64 // 湿度下限
		var t_r_hupper float64 // 湿度上限
		var companyname string
		var id string

		b, _ := Ignore(sensor.Tsn)
		if b {
			log.Println("该设备已忽略:", sensor.Tsn)
			continue
		}

		sqls := fmt.Sprintf("SELECT t_save_t,t_warn FROM device_parameter WHERE t_sn='%s' ORDER BY update_time DESC LIMIT 1", sensor.Tsn)
		company := fmt.Sprintf("SELECT t_name,id FROM company WHERE id='%s'", sensor.TPid)
		device_sensor_parameter := fmt.Sprintf("SELECT t__tlower,t__tupper,t__r_hlower,t__r_hupper FROM device_sensor_parameter WHERE  t_sn='%s' and t__state=1 and t_id = '%s' ORDER BY update_time DESC LIMIT 1", sensor.Tsn, sensor.TId)

		databases.Db.QueryRow(sqls).Scan(&t_save_t, &t_warn)
		databases.Db.QueryRow(company).Scan(&companyname, &id)
		databases.Db.QueryRow(device_sensor_parameter).Scan(&t_tlower, &t_tupper, &t_r_hlower, &t_r_hupper)

		// 查询历史数据
		sql := fmt.Sprintf("SELECT t_time,t_t,t_rh FROM z_device_data_%s WHERE t_id = '%s' ORDER BY t_time DESC LIMIT 10", sensor.Tsn, sensor.TId)
		rows, err := databases.Db.Query(sql)
		if err != nil {
			log.Println("查询数据失败:", err)
			continue
		}
		defer rows.Close()

		deviceDatas := make([]DeviceDatas, 0)
		for rows.Next() {
			var t string
			var t_t, t_rh float64
			rows.Scan(&t, &t_t, &t_rh)
			deviceDatas = append(deviceDatas, DeviceDatas{t_t, t_rh, t})
		}

		if len(deviceDatas) == 10 {
			timeFormat := "2006-01-02 15:04:05"
			start := deviceDatas[0]
			end := deviceDatas[len(deviceDatas)-1]

			startTime, err := time.Parse(timeFormat, start.T_Time)
			if err != nil {
				log.Println("解析时间失败:", err)
				continue
			}
			endTime, err := time.Parse(timeFormat, end.T_Time)
			if err != nil {
				log.Println("解析时间失败:", err)
				continue
			}

			timeDiff := startTime.Sub(endTime).Seconds()
			if IsWarn(deviceDatas, t_tlower, t_tupper, t_r_hlower, t_r_hupper) {
				floatWarn, _ := strconv.ParseFloat(t_warn, 64)
				expectedCount := timeDiff / floatWarn
				actualCount := float64(len(deviceDatas))
				if actualCount > expectedCount {
					//fmt.Println("时间间隔(报警):", timeDiff)
					//fmt.Println("数据预警(报警)", deviceDatas[0], sensor.Tsn)
				}
			} else {
				floatSave, _ := strconv.ParseFloat(t_save_t, 64)
				expectedCount := timeDiff / floatSave
				actualCount := float64(len(deviceDatas))
				//fmt.Println("开始时间与结束时间", timeDiff, startTime, endTime)
				todayStart := time.Now().Truncate(24 * time.Hour)
				if startTime.After(todayStart) || startTime.Equal(todayStart) {
					if actualCount > expectedCount+1 {
						fmt.Println("向上取整：", math.Ceil(expectedCount), "非向上取整：", expectedCount+1, actualCount)
						fmt.Println("时间间隔(保存):", timeDiff, floatSave)
						fmt.Println("数据预警(保存)", deviceDatas[0], sensor.Tsn)

					}
				}
			}
		}
	}
	fmt.Println(message, len(message))
}

// IsWarn 判断是否产生报警数据
func IsWarn(deviceDatas []DeviceDatas, t_tlower, t_tupper, t_r_hlower, t_r_hupper float64) bool {
	for _, data := range deviceDatas {
		if data.T_T < t_tlower || data.T_T > t_tupper || data.T_rh < t_r_hlower || data.T_rh > t_r_hupper {
			return true
		}
	}
	return false
}
