package advertise

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

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, ads, err := tables.AdvertisesQuery(param.Desc, param.Type, param.Limit, param.Page)
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsError("query advertises failed"))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseQueryRes", utils.JsonType{"total": total, "ads": ads}))
}

func removeAdvFile(src string) error {
	index := strings.Index(src, "static/adv")
	if index == -1 {
		return errors.New("error src")
	}
	return os.Remove(src[index:])
}

func Delete(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var ids []uint32
	err := utils.AnyTrans(data, &ids)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	Err := false
	for _, aid := range ids {
		adv := tables.AdvertiseTable{Id: aid}
		err = adv.Get()
		if err != nil {
			utils.Logger.Println(err)
			Err = true
		} else {
			err = removeAdvFile(adv.Src)
			if err != nil {
				utils.Logger.Println(err)
				Err = true
			} else {
				_ = adv.Delete()
			}
		}
	}
	if Err {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseDeleteRes", utils.Fail("删除失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseDeleteRes", utils.Success(nil)))
	go informDevices()
}

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
	}
	adv := tables.AdvertiseTable{Id: param.Id}
	err = adv.Get()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseUpdateRes", utils.Fail("no such advertise")))
		return
	}
	if param.Base64 != "" {
		var ext string
		var reason string
		ext, reason, err = utils.SaveBase64(param.Base64, utils.Format("static/adv/%d", param.Id))
		if err != nil {
			_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseUpdateRes", utils.Fail(reason)))
			return
		}
		adv.Src = utils.Format("%s/static/adv/%d.%s", utils.ServerPrefix, param.Id, ext)
	}
	adv.Order, adv.Type, adv.Time = param.Order, param.Type, utils.TimeNow()
	adv.Duration, adv.Describe = param.Duration, param.Describe
	err = adv.UpdateSelf()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseUpdateRes", utils.Fail("更新失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseUpdateRes", utils.Success(nil)))
	go informDevices()
}

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.Base64 == "" {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseAddRes", utils.Fail("资源不可为空")))
		return
	}
	var id uint32
	id, err = tables.AdvertiseQueryMaxId()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseAddRes", utils.Fail("添加失败 01")))
		return
	}
	id++
	var ext string
	var reason string
	ext, reason, err = utils.SaveBase64(param.Base64, utils.Format("static/adv/%d", id))
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseAddRes", utils.Fail(reason)))
		return
	}
	adv := tables.AdvertiseTable{
		Id: id, Order: param.Order, Type: param.Type, Duration: param.Duration, Describe: param.Describe,
		Src: utils.Format("%s/static/adv/%d.%s", utils.ServerPrefix, id, ext),
	}
	err = adv.Insert()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseAddRes", utils.Fail("添加失败 02")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superConfigAdvertiseAddRes", utils.Success(nil)))
	go informDevices()
}

func informDevices() {
	ads, err := tables.AdvertiseListAll()
	if err != nil {
		return
	}
	for _, item := range utils.SellerDevices {
		if item.Online {
			_ = item.Conn.WriteJSON(utils.WsEvent("advertiseUpdate", ads))
		}
	}
}
