package debugger

import (
	"Wine-Server/utils"
	"Wine-Server/utils/tables"
	"github.com/gorilla/websocket"
)

func keepAlive(conn *websocket.Conn) {
	_ = conn.WriteJSON(utils.WsEvent("pon", nil))
}

func listDevices(conn *websocket.Conn) {
	result := utils.JsonType{}
	for seq, device := range utils.SellerDevices {
		table := tables.DeviceTable{Id: seq}
		_ = table.Get()
		result[seq] = utils.JsonType{
			"seq": seq, "online": device.Online, "location": table.Addr,
			"ppv1": table.Wines[0].Ppv, "ppv2": table.Wines[1].Ppv,
			"ppv3": table.Wines[2].Ppv, "ppv4": table.Wines[3].Ppv,
		}
	}
	_ = conn.WriteJSON(utils.WsEvent("devices", result))
}

func setDebug(conn *websocket.Conn, data any) {
	var param debugParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("params error"))
		return
	}
	if device, exist := utils.SellerDevices[param.Seq]; exist {
		if device.Online {
			_ = device.Conn.WriteJSON(utils.WsEvent("setDebug", param.Debug))
			return
		}
		_ = conn.WriteJSON(utils.WsError("device offline"))
		return
	}
	_ = conn.WriteJSON(utils.WsError("no such device"))
}

func openGate(conn *websocket.Conn, who string, data any) {
	var param openParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("params error"))
		return
	}
	if device, exist := utils.SellerDevices[param.Seq]; exist {
		if device.Online {
			_ = device.Conn.WriteJSON(utils.WsEvent("openGate", utils.JsonType{
				"kind": param.Kind,
				"who":  who,
			}))
			return
		}
		_ = conn.WriteJSON(utils.WsError("device offline"))
		return
	}
	_ = conn.WriteJSON(utils.WsError("no such device"))
}

func setLocation(conn *websocket.Conn, data any) {
	var param locationParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("params error"))
		return
	}
	table := tables.DeviceTable{Id: param.Seq}
	_ = table.Get()
	err = table.Update(utils.JsonType{"addr": param.Loc})
	if err != nil {
		utils.Logger.Printf("update location failed, device[%s], addr[%s], error: %s\n", param.Seq, param.Loc, err)
		_ = conn.WriteJSON(utils.WsError("update location failed"))
	}
	_ = conn.WriteJSON(utils.WsEvent("locationUpdated", nil))
}

func setPpv(conn *websocket.Conn, data any) {
	var param ppvParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("params error"))
		return
	}
	table := tables.DeviceTable{Id: param.Seq}
	_ = table.Get()
	err = table.Update(utils.JsonType{utils.Format("ppv%d", param.Index+1): param.Value})
	if err != nil {
		utils.Logger.Printf(
			"update location failed, device[%s], ppv%d[%s], error: %s\n",
			param.Seq, param.Index, param.Value, err,
		)
		_ = conn.WriteJSON(utils.WsError("update ppv failed"))
	}

	if device, exist := utils.SellerDevices[param.Seq]; exist {
		if device.Online {
			_ = device.Conn.WriteJSON(utils.WsEvent("ppvUpdate", utils.JsonType{
				"index": param.Index,
				"value": param.Value,
			}))
			return
		}
		_ = conn.WriteJSON(utils.WsError("device offline"))
		return
	}
	_ = conn.WriteJSON(utils.WsError("no such device"))
}
