package manager

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

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

func getSecrets(conn *websocket.Conn) {
	_ = conn.WriteJSON(utils.WsEvent("secrets", utils.JsonType{
		"public": utils.ClientPub, "private": utils.ClientPri,
	}))
}

func userLogin(conn *websocket.Conn, data any) (string, error) {
	var param loginParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return "", err
	}
	password, err := utils.Decrypt(param.Password)
	manager := tables.ManagerTable{Account: param.Account}
	err = manager.GetByAcc()
	if err != nil {
		_ = conn.WriteJSON(utils.WsEvent("loginResult", utils.JsonType{"status": false, "msg": "用户不存在"}))
		utils.Logger.Println(err)
		return "", err
	}
	if utils.IsPasswordMatch(manager.Password, password) {
		var token string
		utils.ManagerLock.Lock()
		if _, exist := utils.ManagerWss[manager.Id]; exist {
			utils.ManagerLock.Unlock()
			_ = conn.WriteJSON(utils.WsEvent("loginResult", utils.JsonType{"status": false, "msg": "账户已在别处登录"}))
			return "", errors.New("login other where")
		}
		for {
			token = utils.Format("ManagerToken_%s", utils.RandomString(19, utils.AlphaNumPatten))
			exist, _ := utils.Redis.Exists(utils.WxPayCli, token).Result()
			if exist != 1 {
				_ = utils.Redis.Set(utils.WxPayCli, token, manager.Id, utils.Duration(7*24*60*60)).Err()
				break
			}
		}
		utils.ManagerLock.Unlock()
		_ = conn.WriteJSON(utils.WsEvent("loginResult", utils.Success(utils.JsonType{"token": token, "super": manager.Super})))
		return manager.Id, nil
	} else {
		utils.Logger.Println(utils.HashPassword(password))
		_ = conn.WriteJSON(utils.WsEvent("loginResult", utils.Fail("密码错误")))
		return "", errors.New("password error")
	}
}

func getUserInfo(conn *websocket.Conn, manager *tables.ManagerTable) {
	_ = conn.WriteJSON(utils.WsEvent("userInfo", utils.JsonType{
		"id": manager.Id, "super": manager.Super, "name": manager.Name,
		"order": manager.Order, "income": manager.Income,
	}))
}

func userLogout(conn *websocket.Conn, data any) {
	utils.Redis.Del(utils.WxPayCli, data.(string))
	_ = conn.WriteJSON(utils.WsEvent("logoutResult", nil))
}

func superQueryManager(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	name, _ := data.(string)
	res, err := tables.QueryManager(name)
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsError("query manager failed"))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superQueryManagerRes", res))
}

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

func superUpdateDevice(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var param superUpdateDeviceParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	device := tables.DeviceTable{Id: param.Did}
	err = device.Update(utils.JsonType{"manager": param.Mid, "addr": param.Addr, "mark": param.Mark})
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsEvent("superUpdateDeviceRes", utils.Fail("更新失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superUpdateDeviceRes", utils.Success(nil)))
}

func superBatchAssign(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var param superBatchAssignParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	err = tables.BatchAssignDeviceManager(param.Devices, param.Manager)
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsEvent("superBatchAssignRes", utils.Fail("分配失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superBatchAssignRes", utils.Success(nil)))
}

func superQueryWine(conn *websocket.Conn, manager *tables.ManagerTable, data any) {
	if !manager.Super {
		_ = conn.WriteJSON(utils.WsError("auth failed."))
		return
	}
	var param superQueryWineParam
	err := utils.AnyTrans(data, &param)
	if err != nil {
		_ = conn.WriteJSON(utils.WsError("param error"))
		return
	}
	total, wines, err := tables.QueryWines(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("superQueryWineRes", utils.JsonType{"total": total, "wines": wines}))
}

func superDeleteWine(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.BatchDeleteWine(ids)
	if err != nil {
		utils.Logger.Println(err)
		_ = conn.WriteJSON(utils.WsEvent("superDeleteWineRes", utils.Fail("删除失败")))
		return
	}
	_ = conn.WriteJSON(utils.WsEvent("superDeleteWineRes", utils.Success(nil)))
}
