package service

import (
	"fmt"
	dataDao "iot_manager_service/app/data/dao"
	"iot_manager_service/app/device/dao"
	"iot_manager_service/app/device/model"
	operationDao "iot_manager_service/app/operation/dao"
	"iot_manager_service/app/operation/edge_service"
	operationModel "iot_manager_service/app/operation/model"
	"iot_manager_service/util/common"
	"time"
)

// 中间件管理服务
var WorkbenchService = new(workbenchService)

type workbenchService struct{}

func (s *workbenchService) CountDevice(tenantId string) ([]dao.CountDevice, *common.Errors) {
	counts, err := dao.GetDeviceCount(tenantId)
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}
	return counts, nil
}

func (s *workbenchService) CountAlarm(tenantId string) (*dao.CountAlarm, *common.Errors) {
	count, err := dao.GetAlarmCount(tenantId)
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}
	return count, nil
}

func (s *workbenchService) CountJobTodo(tenantId string) (*dao.CountAlarm, *common.Errors) {
	count, err := dao.GetAlarmCount(tenantId)
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}
	return count, nil
}

func (s *workbenchService) Notification(tenantId string) (*dao.Notification, *common.Errors) {
	notification, err := dao.GetNotification(tenantId)
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}
	return notification, nil
}

func (s *workbenchService) LightRate(tenantId string, req model.ReqLightRates) (*model.RspLightRate, *common.Errors) {

	var list []operationModel.ResponseLightingRate
	var err error
	if req.QueryType == "month" {
		list, err = s.getLightRateData("day", tenantId, operationModel.RequestLightingRateFilter{
			StartTime: req.StartDate,
			EndTime:   req.EndDate,
			QueryType: "day",
		})
	} else {
		list, err = s.getLightRateData("month", tenantId, operationModel.RequestLightingRateFilter{
			StartTime: req.StartDate,
			EndTime:   req.EndDate,
			QueryType: "month",
		})
	}
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}
	var lightRate []model.LightRate
	var energy []model.LightRate
	for _, rate := range list {
		parse, _ := time.Parse("2006-01-02", rate.CountTime)
		if req.QueryType == "month" {
			parse, _ = time.Parse("2006-01-02", rate.CountTime)
		}
		lightRate = append(lightRate, model.LightRate{
			ColumnValue: fmt.Sprintf("%.2f", rate.LightingRate),
			TimeLine:    parse,
		})
		energy = append(energy, model.LightRate{
			ColumnValue: fmt.Sprintf("%.2f", rate.EnergyNum),
			TimeLine:    parse,
		})
	}
	rsp := model.RspLightRate{
		LightRate: lightRate, Energy: energy,
	}
	return &rsp, nil
}

//工作台-采集点
func (s *workbenchService) Aqi(tenantId string) (interface{}, interface{}) {
	aqi, err := dao.GetAqi(tenantId)
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}
	s.GetNewsDate(aqi)
	return aqi, nil
}

func (s *workbenchService) GetNewsDate(vo *dao.OptoSensorVO) *dao.OptoSensorVO {
	//var meteorologicalDataList []omodel.EnvironmentDetail
	//meteorologicalDataVO := omodel.EnvironmentDetail{}
	//meteorologicalDataVO.Sn = vo.Sn
	//meteorologicalDataList = append(meteorologicalDataList, meteorologicalDataVO)
	devId := vo.ID
	environmentData := dataDao.EnvironmentData{DeviceId: devId}
	environmentData.Get()
	vo.RealTimeTemperature = fmt.Sprintf("%.2f ℃", environmentData.Temperature)
	vo.Pm25 = fmt.Sprintf("%.2f ug/m³", environmentData.Pm25)

	aqi := common.CountAqi(float64(environmentData.Pm25), float64(environmentData.Pm10))
	vo.AirIndex = int(aqi)
	vo.AirQuality = common.CalculateAirQuality(aqi)
	vo.EndLineTime = environmentData.PostTime.Format("2006-01-02 15:04:05")
	vo.Humidity = fmt.Sprintf("%.2f %%", environmentData.Humidity)

	vo.Pm10 = fmt.Sprintf("%.2f ug/m³", environmentData.Pm10)
	vo.Noise = fmt.Sprintf("%.2f dB", environmentData.Noise)   //噪声
	vo.Pressure = fmt.Sprintf("%.2f hPa", environmentData.Hpa) //大气压

	vo.Direction = environmentData.WindDirection                                                     //风向
	vo.RealTimeWindSpeed = common.CalculateSpeed(fmt.Sprintf("%.2f", environmentData.WindSpeed/100)) //风力等级
	return vo
}

// getLightRateData 能耗和光照
func (s *workbenchService) getLightRateData(method string, tenantId string, req operationModel.RequestLightingRateFilter) ([]operationModel.ResponseLightingRate, error) {
	lightControl := operationDao.Operation{
		TenantId: tenantId,
	}
	codes, err := lightControl.GetSnList()
	if err != nil {
		return nil, err
	}
	flag := 1  //能耗请求类型：按天
	flag2 := 0 //亮灯率请求类型：按天
	if method == "month" {
		flag = 2  //能耗请求类型：按天
		flag2 = 1 //亮灯率请求类型：按月
	}
	//能耗
	forLightEnergy := edge_service.ForLightEnergy{}
	lightEnergys, err := forLightEnergy.GetLightEnergy(edge_service.ForLightEnergyReq{
		Codes: codes,
		Start: req.StartTime,
		End:   req.EndTime,
		Flag:  flag,
	})
	if err != nil {
		return nil, err
	}
	//亮灯率
	forLightRate := edge_service.ForLightRate{}
	lightRates, err := forLightRate.GetLightRate(edge_service.ForLightRateReq{
		Tenant: tenantId,
		Start:  req.StartTime,
		End:    req.EndTime,
		Flag:   flag2,
	})
	if err != nil {
		return nil, err
	}
	var list []operationModel.ResponseLightingRate
	//fmt.Printf("LightEnergys = %v", LightEnergys)
	var months []string
	if method == "month" {
		months = common.GetTimeMonths(req.StartTime, req.EndTime) //时间范围 月
	} else {
		months = common.GetTimeDays(req.StartTime, req.EndTime) //时间范围 天
	}
	//fmt.Printf("months = %v \n", months)
	for _, month := range months {
		// 能耗数据汇总
		var monthEnergyNum float64 //能耗
		for _, LightEnergy := range lightEnergys {
			for _, data := range LightEnergy {
				if month == data.Date {
					monthEnergyNum += data.Difference
				}
			}
		}
		//亮灯率
		var lightingRate float64
		var lightControlNum, lightingNum int
		for _, rate := range lightRates {
			date := rate.Date
			if method == "month" {
				date = rate.Month + "-01"
			}
			if date == month {
				lightingRate += rate.Rate     //亮灯率
				lightControlNum += rate.Total //灯数
				lightingNum += rate.Number    //亮灯数
			}
		}
		//组合数据到前端接口展示
		list = append(list, operationModel.ResponseLightingRate{
			CountTime:       month,
			EnergyNum:       common.Decimal(monthEnergyNum),
			LightingRate:    common.Decimal(lightingRate),
			LightControlNum: lightControlNum,
			LightingNum:     lightingNum,
		})
	}
	return list, nil
}
