package service

import (
	"encoding/json"
	"fmt"
	"iot_manager_service/app/data/dao"
	"iot_manager_service/app/data/model"
	device "iot_manager_service/app/device/service"
	"iot_manager_service/util/cache"
	"iot_manager_service/util/common"
	"iot_manager_service/util/logger"
	"strconv"
	"time"
)

var EnvironmentDataService = new(environmentDataService)

type environmentDataService struct{}

func (s *environmentDataService) DataSync() {
	devices := device.OptoSensorService.GetAll()
	//fmt.Printf("devices = %v \n", devices)
	if len(devices) == 0 {
		return
	}

	var environmentDatas []dao.EnvironmentData
	for _, d := range devices {
		//fmt.Printf("d.Sn = %v \n", d.Sn)
		creatTime, values := cache.GetDeviceData(d.Sn)
		//fmt.Printf("values = %v \n", values)
		now := time.Now()
		environmentData := dao.EnvironmentData{
			DeviceId:   d.ID,
			PostTime:   creatTime,
			TenantId:   d.TenantId,
			CreateTime: time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, time.Local),
		}
		for key, value := range values {
			switch key {
			case model.ModelInfoNoise:
				environmentData.Noise = value
			case model.ModelInfoPM25:
				environmentData.Pm25 = value
			case model.ModelInfoPM10:
				environmentData.Pm10 = value
			case model.ModelInfoTemprature:
				environmentData.Temperature = value
			case model.ModelInfoHumidity:
				environmentData.Humidity = value
			case model.ModelInfoPressure:
				environmentData.Hpa = value
			case model.ModelInfowindSpeed:
				environmentData.WindSpeed = value
			case model.ModelInfoWindDirection:
				//environmentData.WindDirection = model.CalculateDirection(value)
				environmentData.WindDirection = model.CalculateDirection(value)
			case model.ModelInfoRainfall:
				environmentData.Rainfall = value
			case model.ModelInfoUltravioletRays:
				environmentData.Ultraviolet = value
			case model.ModelInfoLightIntensity:
				environmentData.Illuminance = value
			}
		}
		aqi := common.CountAqi(float64(environmentData.Pm25), float64(environmentData.Pm10))
		value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", aqi), 32)
		environmentData.Air = float32(value)
		environmentData.AirName = common.CalculateAirQuality(float64(environmentData.Air))
		// 7点的数据用于天数据
		environmentData.CreateDate = environmentData.CreateTime.Format("2006-01-02 15:04:06")
		if environmentData.CreateTime.Hour() == 7 {
			environmentData.IsDay = 1
			environmentData.CreateDate = environmentData.CreateTime.Format("2006-01-02")
		}

		environmentDatas = append(environmentDatas, environmentData)
		b, _ := json.Marshal(&environmentData)
		cache.Redis.Set(fmt.Sprintf(model.EnvironmentDataKey, d.ID), string(b), 0)
	}
	//fmt.Printf("environmentDatas = %v \n", environmentDatas)
	environment := &dao.EnvironmentData{}
	err := environment.BatchSave(environmentDatas)
	if err != nil {
		logger.Logger.Errorf("DataSync Hour.BatchSave err = %s", err.Error())
	}

}

func (s *environmentDataService) DayDataSync() {
	summary := &dao.EnvironmentDataSummary{}
	yesterday := time.Now().Add(-24 * time.Hour)
	now := time.Now()
	start := time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, time.Local)
	end := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
	err := summary.DaySummary(start, end)
	if err != nil {
		logger.Logger.Errorf("DayDataSync err = %s", err.Error())
	}
}

func (s *environmentDataService) Get(deviceId int) *dao.EnvironmentData {
	var EnvironmentData dao.EnvironmentData
	result, err := cache.Redis.Get(fmt.Sprintf(model.EnvironmentDataKey, deviceId)).Result()
	if err == nil {
		err = json.Unmarshal([]byte(result), &EnvironmentData)
		if err != nil {
			fmt.Printf("err = %v \n", err)
			return nil
		}
		return &EnvironmentData
	}
	EnvironmentData = dao.EnvironmentData{
		DeviceId: deviceId,
	}
	_ = EnvironmentData.Get()
	return &EnvironmentData
}

func (s *environmentDataService) GetData(deviceId, isDay int, start, end time.Time) ([]dao.EnvironmentData, error) {
	var EnvironmentData dao.EnvironmentData

	EnvironmentData = dao.EnvironmentData{
		DeviceId: deviceId,
		IsDay:    isDay,
	}
	return EnvironmentData.GetByTime(start, end)
}

func (s *environmentDataService) GetScopeData(deviceId int, isDay int, queryType int) (interface{}, error) {
	var chartHistoryList []dao.EnvironmentScopeData
	var chartNowList []dao.EnvironmentScopeData
	var unit string
	switch queryType {
	case 1:
		unit = "aqi"
	case 2:
		unit = "ug/m³"
	case 3:
		unit = "ug/m³"
	case 4:
		unit = "℃"
	case 5:
		unit = "%"
	case 6:
		unit = "m/s"
	case 7:
		unit = "hPa"
	case 8:
		unit = "dB"
	}
	var EnvironmentData dao.EnvironmentData

	EnvironmentData = dao.EnvironmentData{
		DeviceId: deviceId,
		IsDay:    isDay,
	}
	chartHistoryList = EnvironmentData.GetEnvironmentScope(queryType, "history")
	chartNowList = EnvironmentData.GetEnvironmentScope(queryType, "now")
	data := make(map[string]interface{})
	data["unit"] = unit
	data["chartHistoryList"] = chartHistoryList
	data["chartNowList"] = chartNowList
	return data, nil
}
