package protocol

import (
	"fmt"
	"lc/common/util"
	"strconv"
	"time"

	"github.com/google/uuid"
)

const (
	electricOverloadAlarm = 10001 //电流过载故障
	underVoltageAlarm     = 10002 //欠压故障
	overVoltageAlarm      = 10003 //过压故障
	leakageAlarm          = 10004 //漏电故障
	slantAlarm            = 10005 //终端倾斜故障（带倾斜传感器的控制器需定制）
	powerFactorAlarm      = 10006 //功率因数故障
)

const (
	Apikey = "05b9cdff196d746709bc308bcf2c46af"

	//msgType
	MT_TURNON          = "turnon"
	MT_TURNOFF         = "turnoff"
	MT_DIMMER          = "dimmer" //调光
	MT_STRATEGY        = "strategy"
	MT_CLEARSTRATEGY   = "clearStrategy"
	MT_REPORTFREQUENCY = "ReportFrequency" //上行
	MT_REPORT          = "report"
	MT_SEARCHINFO      = "searchInfo"
	MT_ONLINE          = "online"
	MT_OFFLINE         = "offline"
	MT_ALARM           = "alarm"
	MT_ADD             = "add" //控制器类型指定为add（增加单灯）/update（修改单灯）/delete（删除单灯）
	MT_UPDATE          = "update"
	MT_DELETE          = "delete"
	MT_CAMLightPARAM   = "cameralightparam"

	// actionType为whole时，只关注masterSn;
	// actionType为multi时，只关注snGroup;
	//控制类型为whole（集控）/multi（多控，默认）
	AT_WHOLE = "whole"
	AT_MULTI = "multi"

	//lampStatus
	LS_ON  = "on" //单灯状态上行
	LS_OFF = "off"
)

type HLWLZB_Pack struct {
	MsgType    string `json:"msgType,omitempty"`
	ActionType string `json:"actionType,omitempty"`
	MasterSn   string `json:"masterSn"`
}

func (o *HLWLZB_Pack) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

//---------------------------------告警状态BEGIN-----------------------
// { "snGroup": [ { "serialNumber": "00037F101219", // 集控序列号
// 						"alarmStatus": 0, // 告警状态（0解除/1触发）
// 						 "alarmCode": "10001", // 告警码
// 						"alarmValue": "220" // 电压值 },
// 				{ "serialNumber": "00037F101220",
// 						"alarmStatus": 1,
// 						 "alarmCode": "10002",
// 						 "alarmValue": "270" // 电压值 },
//  			],"msgType": "alarm",
// 	"ts": "1530755999",
// 	"masterSn": "00037F101219", // 涉及到集控则必填,多个集控的单灯按多条信息发送
// 	"uuid": "1ab4f7b75a044869bccdd193d4914772" }

// 内嵌结构snGroup
type SNGROUP_AS struct {
	serialNumber string `json:"serialNumber"`
	alarmStatus  string `json:"alarmStatus"`
	alarmValue   string `json:"alarmValue"`
	alarmCode    string `json:"alarmCode"`
}

type HLWLZB_AlermStatus_Up struct {
	SnGroup  []SNGROUP_AS `json:"snGroup"`
	Ts       string       `json:"ts"`
	MasterSn string       `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid     string       `json:"uuid"`
}

func (o *HLWLZB_AlermStatus_Up) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// ---------------------------------告警状态END-----------------------
// ---------------------------------灯具状态定时上报BEGIN-----------------------
// 和查询上报数据包一样
// ---------------------------------灯具状态定时上报END-----------------------
// ---------------------------------查询灯具状态（集控方式）BEGIN-----------------------
// { "apikey": "9af4d8381781baccb0f915e554f8798d",
// "msgType": "searchInfo",
//
//	"actionType": "whole",
//
// "ts": "1530755999",
// "masterSn": "00037F101219", // 涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
//
//	"uuid": "12323a0239bccdd193d49231231231" }
//
// 查询灯具状态 集控示例
type HLWLZB_QueryLampStatus struct {
	Apikey     string `json:"apikey"`
	MsgType    string `json:"msgType"` //turnoff, dimmer
	ActionType string `json:"actionType"`
	Ts         int64  `json:"ts"`
	MasterSn   string `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string `json:"uuid"`
}

// 组包
func (o *HLWLZB_QueryLampStatus) EnCode(id string) (string, error) {

	o.Apikey = Apikey
	o.MsgType = MT_SEARCHINFO
	o.ActionType = AT_WHOLE
	o.Ts = util.MlNow().Unix()
	o.MasterSn = id
	o.Uuid = uuid.New().String()
	return json.MarshalToString(o)
}

// { "actionType": "whole",
//
//	"errorCode": "0", // 0表示命令接收成功
//
// "masterSn": "00037F101219",
// "msgType": "searchInfo",
//
//	"ts": "1634993991",
//
// "uuid": "12218701-506a-42219-a455-c11111b2" }
// 查询灯具状态 ack 集控示例
type HLWLZB_QueryLampStatus_Ack struct {
	ErrorCode  int16  `json:"errorCode"`
	MsgType    string `json:"msgType"`
	ActionType string `json:"actionType"`
	Ts         int64  `json:"ts"`
	MasterSn   string `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string `json:"uuid"`
}

func (o *HLWLZB_QueryLampStatus_Ack) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// "snGroup": [ { "serialNumber": "00037F101219", // 集控序列号
//
//		"lux": "100.0", // 调光值（单位：百分比）
//		 "voltage": "237.0", // 电压（单位：伏）
//		 "electricity": "0.45", // 电流（单位：安）
//		"power": "100", // 功率（单位：瓦）
//		 "powerFactor": "0.94", // 功率因数
//		"energy": "100.0", // 总能耗（单位：千瓦时）
//		 "lampStatus": "on" //灯具状态（on/off） },
//	{ "serialNumber": "00037F101220", // 单控序列号
//	"lux": "100.0",
//	"voltage": "237.0",
//	"electricity": "0.45",
//	 "power": "100",
//	 "powerFactor": "0.94",
//	"energy": "100.0",
//	"lampStatus": "on" }...... ],
//
// 内嵌结构snGroup
type SNGROUP_QLS struct {
	StateError
	SerialNumber string `json:"serialNumber"`
	Lux          string `json:"lux"`
	Voltage      string `json:"voltage"`
	Electricity  string `json:"electricity"`
	Power        string `json:"power"`
	PowerFactor  string `json:"powerFactor"`
	Energy       string `json:"energy"`
	LampStatus   string `json:"lampStatus"`
}

// { "masterSn": "00037F101219",
//
//	"msgType": "report",
//
// "snGroup": [ { "serialNumber": "00037F101219", // 集控序列号
//
//				"lux": "100.0", // 调光值（单位：百分比）
//				 "voltage": "237.0", // 电压（单位：伏）
//				 "electricity": "0.45", // 电流（单位：安）
//				"power": "100", // 功率（单位：瓦）
//				 "powerFactor": "0.94", // 功率因数
//				"energy": "100.0", // 总能耗（单位：千瓦时）
//				 "lampStatus": "on" //灯具状态（on/off） },
//			{ "serialNumber": "00037F101220", // 单控序列号
//			"voltage": "237.0",
//			"electricity": "0.45",
//			 "power": "100",
//			 "powerFactor": "0.94",
//			"energy": "100.0",
//			"lampStatus": "on" }...... ],
//	"ts": "1631953995",
//	"uuid": "112301-506a-4489-a455-c5123fccb3" }
//
// 查询灯具返回数据，包括能源信息 集控示例
type HLWLZB_QueryLampStatus_Back struct {
	MsgType  string        `json:"msgType"`
	SnGroup  []SNGROUP_QLS `json:"snGroup"`
	Ts       string        `json:"ts"`
	MasterSn string        `json:"masterSn"`
	Uuid     string        `json:"uuid"`
}

func (o *HLWLZB_QueryLampStatus_Back) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

//---------------------------------查询灯具状态（集控方式）END-----------------------

// ---------------------------------手动开/关灯 BEGIN-----------------------
type SNGROUP struct {
	SerialNumber string `json:"serialNumber"`
}

// 手动开/关灯 多控
type HLWLZB_Switch struct {
	Apikey     string    `json:"apikey"`
	SnGroup    []SNGROUP `json:"snGroup"`
	MsgType    string    `json:"msgType"` //turnoff, dimmer
	ActionType string    `json:"actionType"`
	Lux        uint8     `json:"lux"` //调光值，仅在dimmer时有效
	Ts         int64     `json:"ts"`
	MasterSn   string    `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string    `json:"uuid"`
}

// 组包 1开，0关
func (o *HLWLZB_Switch) EnCode(id, gid string, seq uint64, Switch, brightness uint8,
	recovery uint, lampIDs []uint32) (string, error) {

	o.Apikey = Apikey
	o.SnGroup = append(o.SnGroup, SNGROUP{SerialNumber: id})
	o.ActionType = AT_MULTI
	o.Lux = brightness
	o.Ts = util.MlNow().Unix()
	o.MasterSn = id
	o.Uuid = uuid.New().String()

	if Switch == 1 {
		if brightness > 0 {
			o.MsgType = MT_DIMMER
		} else {
			o.MsgType = MT_TURNON
		}
	} else if Switch == 0 {
		o.MsgType = MT_TURNOFF
	}

	return json.MarshalToString(o)
}

// { "apikey": "9af4d8381781baccb0f915e554f8798d",
//  "msgType": "turnon", // turnoff, dimmer
// "actionType": "whole",
//  "lux": "80", // 调光值，仅在dimmer时有效
// "ts": "1530755999",
// "masterSn": "00037F101219", // 涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
// "uuid": "1ab4f7b75a044869bccdd193d4914773" }

// 手动开/关灯 集控
type HLWLZB_Whole_Switch struct {
	Apikey     string `json:"apikey"`
	MsgType    string `json:"msgType"` //turnoff, dimmer
	ActionType string `json:"actionType"`
	Lux        uint8  `json:"lux"` //调光值，仅在dimmer时有效
	Ts         int64  `json:"ts"`
	MasterSn   string `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string `json:"uuid"`
}

// 组包 1开，0关
func (o *HLWLZB_Whole_Switch) EnCode(id, gid string, seq uint64, Switch, brightness uint8,
	recovery uint, lampIDs []uint32) (string, error) {

	o.Apikey = Apikey
	o.ActionType = AT_WHOLE
	o.Lux = brightness
	o.Ts = util.MlNow().Unix()
	o.MasterSn = id
	o.Uuid = uuid.New().String()

	if Switch == 1 {
		if brightness > 0 {
			o.MsgType = MT_DIMMER
		} else {
			o.MsgType = MT_TURNON
		}
	} else if Switch == 0 {
		o.MsgType = MT_TURNOFF
	}

	return json.MarshalToString(o)
}

// { "msgType": "turnon",
// "actionType": "whole",
// "lux": "80" // 仅在dimmer时有效
// "errorCode": "0", // 控制状态失败返回对应错误码信息
// "ts": "1530755999",
// "masterSn": "00037F101219", // 涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
// "uuid": "1ab4f7b75a044869bccdd193d4914774" }
// 集控方式
type HLWLZB_Switch_Whole_Ack struct {
	MsgType    string `json:"msgType"` //turnoff, dimmer
	ActionType string `json:"actionType"`
	Lux        uint8  `json:"lux"` //调光值，仅在dimmer时有效
	ErrorCode  int16  `json:"errorCode"`
	Ts         string `json:"ts"`
	MasterSn   string `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string `json:"uuid"`
}

func (o *HLWLZB_Switch_Whole_Ack) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// { "snGroup":
//
//	 		[ {"serialNumber": "00037F101219"},
//				{"serialNumber": "00037F101220"},
//				{"serialNumber": "00037F101221"}, ...... ],（必填）
//	"msgType": "turnon", // turnoff, dimmer
//	"actionType": "multi",
//	"lux": "80", // 仅在dimmer时有效
//	"errorCode": "0", // 控制状态失败返回对应错误码信息
//	"ts": "1530755999",
//	"masterSn": "00037F101219", // 涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
//	"uuid": "1ab4f7b75a044869bccdd193d4914776" }
//
// 多控方式
type HLWLZB_Switch_Multi_Ack struct {
	SnGroup    []SNGROUP `json:"snGroup"`
	MsgType    string    `json:"msgType"` //turnoff, dimmer
	ActionType string    `json:"actionType"`
	Lux        uint8     `json:"lux"` //调光值，仅在dimmer时有效
	ErrorCode  uint16    `json:"errorCode"`
	Ts         string    `json:"ts"`
	MasterSn   string    `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string    `json:"uuid"`
}

func (o *HLWLZB_Switch_Multi_Ack) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

//---------------------------------手动开/关灯 END-----------------------

type Pack_HLWLZB_Switch struct {
	Data HLWLZB_Switch `json:"data"`
}

func (o *Pack_HLWLZB_Switch) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// 开关灯时间
type HLWLZB_OnOffTime struct {
	OnHour     uint8 `json:"onhour"`
	OnMinite   uint8 `json:"onminite"`
	OffHour    uint8 `json:"offhour"`
	OffMinite  uint8 `json:"offminite"`
	Brightness uint8 `json:"brightness"` //亮度0~100
}

func (o *HLWLZB_OnOffTime) SetData(onhour, onminite, offhour, offminite, brightness uint8) {
	o.OnHour = onhour
	o.OnMinite = onminite
	o.OffHour = offhour
	o.OffMinite = offminite
	o.Brightness = brightness
}

func (o *HLWLZB_OnOffTime) InTimeRange(t time.Time) bool {
	h := uint8(t.Hour())
	m := uint8(t.Minute())

	if o.OnHour > o.OffHour { //跨日情况,例如19:30~5:30，开灯时间大于关灯时间
		if h > o.OnHour || h < o.OffHour || (h == o.OnHour && m >= o.OnMinite) ||
			(h == o.OffHour && m <= o.OffMinite) {
			return true
		}
	} else if o.OnHour < o.OffHour { //开灯时间小于关灯时间
		if (h > o.OnHour && h < o.OffHour) ||
			(h == o.OnHour && m >= o.OnMinite) ||
			(h == o.OffHour && m <= o.OffMinite) {
			return true
		}
	} else { //开灯时间等于关灯时间
		if h == o.OnHour && m >= o.OnMinite && m <= o.OffMinite {
			return true
		}
	}
	return false
}

//---------------------------------开关灯时间策略 BEGIN-----------------------

// {"apikey": "9af4d8381781baccb0f915e554f8798d",
// "msgType": "strategy",
// "actionType": "whole",
// "strategy": [ {"timer": "05:00:00","lux": "50"}, // timer：调光时间，lux：调光值 {"timer": "06:00:00","lux": "0"}, ...... ],
// "ts": "1530755999",
// "masterSn": "00037F101219", //集控序列号
// "uuid": "1ab4f7b75a044869bccdd193d4911889"}

// 开关灯时间设备格式
type STRATEGY struct {
	Timer string `json:"timer"`
	Lux   uint8  `json:"lux"`
}

// 策略
type Pack_HLSetOnOffTime struct {
	Apikey     string     `json:"apikey"`
	MsgType    string     `json:"msgType"` //strategy
	ActionType string     `json:"actionType"`
	Strategy   []STRATEGY `json:"strategy"`
	Ts         int64      `json:"ts"`
	MasterSn   string     `json:"masterSn"` // 集控的必填
	Uuid       string     `json:"uuid"`
}

// 设置开关灯时间只支持集控,id为集控的id
func (o *Pack_HLSetOnOffTime) EnCode(id, gid string, seq uint64, lampIDs []uint32, onofftime []HLWLZB_OnOffTime) (string, error) {

	o.Apikey = Apikey
	o.MsgType = "strategy"
	o.ActionType = "whole"
	o.Ts = util.MlNow().Unix()
	o.MasterSn = id
	o.Uuid = uuid.New().String()

	//[{\"onhour\":19,\"onminite\":7,\"offhour\":5,\"offminite\":37,\"brightness\":50}]","time":"2022-05-13T14:18:19+08:00"}

	for _, k := range onofftime {

		str := fmt.Sprintf("%s:%s:00", strconv.Itoa(int(k.OnHour)), strconv.Itoa(int(k.OnMinite)))
		// str := strconv.Itoa(int(k.OnHour)) + ":" + strconv.Itoa(int(k.OnMinite)) + ":00"
		o.Strategy = append(o.Strategy, STRATEGY{Timer: str, Lux: k.Brightness}) //开
		str = fmt.Sprintf("%s:%s:00", strconv.Itoa(int(k.OffHour)), strconv.Itoa(int(k.OffMinite)))

		// str = strconv.Itoa(int(k.OffHour)) + ":" + strconv.Itoa(int(k.OffMinite)) + ":00"
		o.Strategy = append(o.Strategy, STRATEGY{Timer: str, Lux: 0}) //关
	}

	return json.MarshalToString(o)
}
func (o *Pack_HLSetOnOffTime) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// { "actionType": "whole",
// "errorCode": "0", // 控制状态失败返回对应错误码信息
// "masterSn": "00037F101219", // 集控序列号
//
//	"msgType": "strategy",
//
// "strategy": [ { "lux": "100", "timer": "18:30:00" },{ "lux": "0", "timer": "05:00:00" } ],
// "ts": "1631870013",
// "uuid": "1ab4f7b75a044869bccdd193d4910921" }
type Pack_HLSetOnOffTime_Ack struct {
	MsgType    string     `json:"msgType"` //strategy
	ActionType string     `json:"actionType"`
	ErrorCode  int16      `json:"errorCode"`
	Strategy   []STRATEGY `json:"strategy"`
	Ts         string     `json:"ts"`
	MasterSn   string     `json:"masterSn"` // 集控的必填
	Uuid       string     `json:"uuid"`
}

func (o *Pack_HLSetOnOffTime_Ack) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// { "apikey": "9af4d8381781baccb0f915e554f8798d",
// "msgType": "clearStrategy",
// "actionType": "whole",
// "ts": "1530755999",
// "masterSn": "00037F101219", //集控序列号
//
//	"uuid": "1ab4f7b75a044869bccdd193d4914112" }
//
// 清空关闭策略
type Pack_HLClearStrategy struct {
	Apikey     string `json:"apikey"`
	MsgType    string `json:"msgType"` //strategy
	ActionType string `json:"actionType"`
	Ts         int64  `json:"ts"`
	MasterSn   string `json:"masterSn"` // 集控的必填
	Uuid       string `json:"uuid"`
}

// 清空关闭策略
func (o *Pack_HLClearStrategy) EnCode(id string) (string, error) {

	o.Apikey = Apikey
	o.MsgType = MT_CLEARSTRATEGY
	o.ActionType = AT_WHOLE
	o.Ts = util.MlNow().Unix()
	o.MasterSn = id
	o.Uuid = uuid.New().String()

	return json.MarshalToString(o)
}

// { "msgType": "clearStrategy",
// "actionType": "whole",
//
//	"errorCode": "0", // 控制状态失败返回对应错误码信息
//
// "ts": "1530755999",
//
//	"masterSn": "00037F101219", // 集控序列号
//	"uuid": "1ab4f7b75a044869bccdd193d4913211" }
//
// 关闭策略ack
type Pack_HLClearStrategy_Ack struct {
	MsgType    string `json:"msgType"` //strategy
	ActionType string `json:"actionType"`
	ErrorCode  int16  `json:"errorCode"`
	Ts         string `json:"ts"`
	MasterSn   string `json:"masterSn"` // 集控的必填
	Uuid       string `json:"uuid"`
}

func (o *Pack_HLClearStrategy_Ack) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// ---------------------------------开关灯时间策略 END-----------------------
// ---------------------------------离线上线begin-----------------------
// 离线 {"masterSn":"301056","msgType":"offline",//and online
//
//			"snGroup":[{"serialNumber":"301056"}],
//	"ts":"1653445142","uuid":"40a47d85-2ebb-41ab-a6d9-6aad4b934d02"}
//
// 离线上线只有集控器上报
type HLWLZB_OnOfflineStatus_Up struct {
	MsgType  string    `json:"msgType"`
	SnGroup  []SNGROUP `json:"snGroup"`
	Ts       string    `json:"ts"`
	MasterSn string    `json:"masterSn"`
	Uuid     string    `json:"uuid"`
}

func (o *HLWLZB_OnOfflineStatus_Up) DeCode(message string) error {
	return json.UnmarshalFromString(message, o)
}

// ---------------------------------离线上线end-----------------------
// ---------------------------------初始化下发频率begin-----------------------
// { "apikey": "05b9cdff196d746709bc308bcf2c46af",
// "msgType": "ReportFrequency",
// "actionType": "whole",
// "interval": "10",
// "ts": "1530755999",
// "masterSn": "301056",
// "uuid": "1ab4f7b75a04486666d4911231" }
type HLWLZB_Frequency_Down struct {
	Apikey     string `json:"apikey"`
	MsgType    string `json:"msgType"` //turnoff, dimmer
	Interval   uint   `json:"interval"`
	ActionType string `json:"actionType"`
	Ts         int64  `json:"ts"`
	MasterSn   string `json:"masterSn"` //涉及到集控的必填,分属多个不同集控的单灯按多条信息发送
	Uuid       string `json:"uuid"`
}

// 组包
func (o *HLWLZB_Frequency_Down) EnCode(id string, interval uint) (string, error) {

	o.Apikey = Apikey
	o.MsgType = MT_REPORTFREQUENCY
	o.ActionType = AT_WHOLE
	o.Ts = util.MlNow().Unix()
	o.MasterSn = id
	o.Uuid = uuid.New().String()
	o.Interval = interval
	return json.MarshalToString(o)
}

//---------------------------------初始化下发频率 end-----------------------
