package wine

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

func Query(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var param queryParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	total, wines, err := tables.WinesQuery(param.Cond, param.Limit, param.Page)
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsError("query wines failed"))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigWineQueryRes", utils.JsonType{"total": total, "wines": wines}))
}

func Delete(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var ids []uint16
	err := utils.AnyTrans(data, &ids)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	err = tables.WinesDelete(ids)
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineDeleteRes", utils.Fail("删除失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigWineDeleteRes", utils.Success(nil)))
}

func Add(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var param addParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	if param.Image == "" {
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineAddRes", utils.Fail("图片数据不可为空")))
		return
	}
	var id uint16
	id, err = tables.WineQueryMaxId()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineAddRes", utils.Fail("添加失败 01")))
		return
	}
	id++
	var ext string
	var reason string
	ext, reason, err = utils.SaveBase64(param.Image, utils.Format("static/wine/%d", id))
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineAddRes", utils.Fail(reason)))
		return
	}
	wine := tables.WineTable{
		Id: id, Name: param.Name, Price: param.Price, Degree: param.Degree,
		Density: param.Density, Describe: param.Describe,
		Picture: utils.Format("%s/static/wine/%d.%s", utils.ServerPrefix, id, ext),
	}
	err = wine.Insert()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineAddRes", utils.Fail("添加失败 02")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigWineAddRes", utils.Success(nil)))
}

func Update(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var param updateParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	wine := &tables.WineTable{Id: param.Id}
	err = wine.Get()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineUpdateRes", utils.Fail("no such wine")))
		return
	}
	if param.Image != "" {
		var ext string
		var reason string
		ext, reason, err = utils.SaveBase64(param.Image, utils.Format("static/wine/%d", param.Id))
		if err != nil {
			_ = conn.WriteJSON(utils.WsEvent("superConfigWineUpdateRes", utils.Fail(reason)))
			return
		}
		wine.Picture = utils.Format("%s/static/wine/%d.%s", utils.ServerPrefix, param.Id, ext)
	}
	wine.Name, wine.Describe = param.Name, param.Describe
	wine.Price, wine.Degree, wine.Density = param.Price, param.Degree, param.Density
	err = wine.UpdateSelf()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigWineUpdateRes", utils.Fail("更新失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigWineUpdateRes", utils.Success(nil)))
	go informDevices(wine)
}

func informDevices(wine *tables.WineTable) {
	list, err := tables.DevicesWithTheWine(wine.Id)
	if err != nil {
		utils.Logger.Println(err)
		return
	}
	for _, id := range list {
		if item, din := utils.SellerDevices[id]; din && item.Online {
			_ = item.Conn.WriteJSON(utils.WsEvent("wineUpdate", utils.JsonType{
				"id": wine.Id, "name": wine.Name, "price": wine.Price, "degree": wine.Degree,
				"density": wine.Density, "describe": wine.Describe,
			}))
		}
	}
}
