package admin

import (
	"fmt"
	"server/dao"
	"server/model/common/request"
	"server/model/common/response"
	"server/utils/data"
	"server/utils/logger"
	"server/utils/protocol"
	"strconv"
	"time"
)

type DeviceService struct{}

func (ds *DeviceService) QueryAllDevices() ([]dao.Device, error) {
	return dao.QueryAllDevices()
}

func (ds *DeviceService) QueryDeviceList(info request.DeviceSearch) (devices []dao.Device, total int64, err error) {
	limit := info.PageInfo.PageSize
	offset := info.PageInfo.PageSize * (info.PageInfo.Page - 1)

	return dao.QueryDeviceList(info.Sn, info.Name, info.Genre, limit, offset)
}

func (ds *DeviceService) GenerateDeviceFile(id int) (data response.DeviceFileData, err error) {
	devices, err := dao.QueryDeviceByTunnelId(id)
	if err != nil {
		return data, err
	}

	for _, d := range devices {
		if d.DeviceGenre.Type == "环境设备" {
			envDev := response.EnvDev{
				Name:     d.Name,
				Sn:       d.Sn,
				Address:  d.Address,
				TaskTime: d.TaskTime,
				WaitTime: d.WaitTime,
				SerialId: d.SerialId,
			}

			data.EnvDev = append(data.EnvDev, envDev)
		} else if d.DeviceGenre.Type == "开关设备" {
			lampDev := response.LampDev{
				Sn:       d.Sn,
				Name:     d.Name,
				Address:  d.Address,
				RadarId:  d.RadarId,
				SerialId: d.SerialId,
			}

			data.LampDev = append(data.LampDev, lampDev)
		}
	}

	return data, nil
}

func (ds *DeviceService) DeviceSwitch(info request.SwitchTunnel) error {
	device, err := dao.QueryDeviceByTunnelSnAndRadarId(info.TunnelSn, info.RadarId)
	if err != nil {
		return err
	}
	err = dao.UpdateRelayState(device.Sn, info.RelayId, info.State)
	if err != nil {
		return err
	}
	var i int
	if info.State {
		i = 1
	} else {
		i = 0
	}
	data1 := strconv.Itoa(info.RadarId) + strconv.Itoa(info.RelayId) + strconv.Itoa(i)
	err = MqttService.Publish(MqttService.GetTopic(info.TunnelSn, protocol.TopicSwitchControl), []byte(data1))
	if err != nil {
		return fmt.Errorf("error updating: %v", err)
	}
	return nil
}

func (ds *DeviceService) CreateDevice(device dao.Device) error {
	tunnel, err := dao.QueryTunnelById(device.TunnelId)
	if err != nil {
		return err
	}
	genre, err := dao.QueryDeviceGenreByID(device.Genre)
	if err != nil {
		return err
	}

	if genre.Name == tunnel.SwitchType && genre.Type == "开关设备" {
		return fmt.Errorf("开关设备需安照隧道需求添加")
	}

	return device.CreateDevice()
}

func (ds *DeviceService) UpdateDevice(device dao.Device) error {
	tunnel, err := dao.QueryTunnelById(device.TunnelId)
	if err != nil {
		return err
	}

	if device.DeviceGenre.Name != tunnel.SwitchType && device.DeviceGenre.Type == "开关设备" {
		return fmt.Errorf("开关设备需安照隧道需求添加")
	}

	device.DeviceGenre = dao.DeviceGenre{}
	device.Tunnel = dao.Tunnel{}

	return device.UpdateDevice()
}

func (ds *DeviceService) DeleteDevice(id int) error {
	return dao.DeleteDevice(id)
}

func InductanceStatistics() error {
	tunnels, _ := dao.QueryAllTunnels()

	for _, tunnel := range tunnels {
		device, _ := dao.QueryDGDeviceByTunnelSn(tunnel.TunnelSn)
		list, err := dao.QueryInductanceDetailsOneDay(device.Sn)
		if err != nil {
			return err
		}
		preprocessData, err := data.PreprocessData(list)
		if err != nil {
			return err
		}

		consumption := data.CalculateDailyEnergyConsumption(preprocessData)

		err = dao.PowerStatistics{
			TunnelSn:         tunnel.TunnelSn,
			TotalActivePower: consumption,
			UploadTime:       time.Now().Add(-1).Local().Format("2006-01-02"),
		}.CreatePowerStatistics()

		logger.Get().Errorf("电感数据统计 隧道：%v 错误%v", tunnel.TunnelSn, err)
	}

	return nil
}

func (ds *DeviceService) QueryPowerStatisticsBySn(sn string) (powerStatistics []dao.PowerStatistics, err error) {
	return dao.QueryPowerStatisticsBySn(sn)
}
