package services

import (
	"sparrow/pkg/models"
	"sparrow/pkg/rpcs"
	"sparrow/pkg/server"
	"sparrow/services/knowoapi/model"
)

// DeviceService device service接口
type DeviceService interface {
	// 获取厂商已经激活的设备总数
	GetDeviceCount(vendorid string) (int, error)
	//返回厂商某天激活的设备数
	GetActiveNumberOfDate(vendor string, datetime string) (int, error)
	//获取厂商某天活跃的设备数
	GetLivelyCountOfDate(string, string) (int, error)
	//获取近N日激活设备数据
	GetActiveOfNumDays(string, int) ([]map[string]interface{}, error)
	//获取近N日活跃设备数据
	GetLivelyOfNumDays(string, int) ([]map[string]interface{}, error)
	//获取已经激活的设备列表
	GetDevices(vendorid string, proid, pi, ps int, deviceid string) ([]*models.Devices, int, error)
	//获取用户下所有设备的数量，在线设备的数量，离线设备的数量
	GetDevicesCountByVenderId(vendorid string) (map[string]interface{}, error)
}

type deviceservice struct {
	models *model.All
}

// NewDeviceService create device service
func NewDeviceService(models *model.All) DeviceService {
	return deviceservice{
		models: models,
	}
}
func (a deviceservice) GetDevices(vendorid string, proid, pi, ps int, deviceid string) ([]*models.Devices, int, error) {

	data, total, err := a.models.Device.GetDevices(vendorid, proid, pi, ps, deviceid)

	if err != nil {
		return nil, 0, err
	}

	dataMap := make([]*models.Devices, 0)

	for _, device := range data {

		onlineargs := rpcs.ArgsGetDeviceOnlineStatus{
			Id: device.DeviceIdentifier,
		}

		onlinereply := rpcs.ReplyGetDeviceOnlineStatus{}
		err = server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceOnlineStatus", onlineargs, &onlinereply)
		if err != nil && err.Error() != "redigo: nil returned" {
			server.Log.Errorf("get devie online status error: %v", err)

			return nil, 0, err
		}

		devices := new(models.Devices)

		devices.Device = device

		if int(onlinereply.HeartbeatInterval) > 0 && len(onlinereply.ClientIP) > 0 {
			devices.Status = 1
		}

		dataMap = append(dataMap, devices)
	}

	return dataMap, total, nil
}
func (a deviceservice) GetDeviceCount(vendorid string) (int, error) {
	return a.models.Device.GetDeviceCount(vendorid)
}
func (a deviceservice) GetActiveNumberOfDate(vendorid string, datetime string) (int, error) {
	return a.models.Device.GetActiveNumberOfDate(vendorid, datetime)
}
func (a deviceservice) GetLivelyCountOfDate(vendorid string, datetime string) (int, error) {
	return a.models.Device.GetLivelyCountOfDate(vendorid, datetime)
}
func (a deviceservice) GetActiveOfNumDays(vendorid string, days int) ([]map[string]interface{}, error) {
	return a.models.Device.GetActiveOfNumDays(vendorid, days)
}
func (a deviceservice) GetLivelyOfNumDays(vendorid string, days int) ([]map[string]interface{}, error) {
	return a.models.Device.GetLivelyOfNumDays(vendorid, days)
}
func (a deviceservice) GetDevicesCountByVenderId(vendorid string) (map[string]interface{}, error) {
	data, err := a.models.Device.GetDevicesByVenderId(vendorid)

	if err != nil {
		return nil, err
	}

	var onlineCount int

	var offlineCount int
	for _, device := range data {
		onlineargs := rpcs.ArgsGetDeviceOnlineStatus{
			Id: device.DeviceIdentifier,
		}
		onlinereply := rpcs.ReplyGetDeviceOnlineStatus{}
		err = server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceOnlineStatus", onlineargs, &onlinereply)
		if err != nil && err.Error() != "redigo: nil returned" {
			server.Log.Errorf("get devie online status error: %v", err)
			return nil, err
		}

		if int(onlinereply.HeartbeatInterval) > 0 && len(onlinereply.ClientIP) > 0 {
			onlineCount += 1
		} else {
			offlineCount += 1
		}
	}

	deviceCount := map[string]interface{}{
		"TotalData":    len(data),
		"OnlineCount":  onlineCount,
		"OfflineCount": offlineCount,
	}

	return deviceCount, nil
}
