package game

import (
	"encoding/json"
	"log"
	"microGame/app/usercenter/cmd/api/internal/types"
	"time"

	"github.com/gorilla/websocket"
)

const (
	writeWait      = 10 * time.Second
	pongWait       = 60 * time.Second
	pingPeriod     = (pongWait * 9) / 10
	maxMessageSize = 512
	BufSize        = 256
)

func (o *Player) ReadPump() {
	defer func() {
		o.SvcCtx.Hub.Unregister <- o
		_ = o.Conn.Close()
	}()
	o.Conn.SetReadLimit(maxMessageSize)
	_ = o.Conn.SetReadDeadline(time.Now().Add(pongWait))
	o.Conn.SetPongHandler(func(string) error { _ = o.Conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	for {
		_, message, err := o.Conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
				log.Printf("-- 连接出错 => error: %v", err)
			}
			break
		}
		if err = json.Unmarshal(message, &types.WSMessage{}); err != nil {
			log.Printf("-- 消息解析出错 => message: %v", string(message))
			_ = o.Conn.Close()
			break
		}
		o.SvcCtx.Hub.Broadcast <- message
	}
}

func (o *Player) WritePump() {
	ticker := time.NewTicker(pingPeriod)
	defer func() {
		ticker.Stop()
		_ = o.Conn.Close()
	}()

	for {
		select {
		case message, ok := <-o.Send:

			err := o.Conn.SetWriteDeadline(time.Now().Add(writeWait))
			if !ok || err != nil {
				_ = o.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}

			w, err := o.Conn.NextWriter(websocket.TextMessage)
			if err != nil {
				return
			}
			_, _ = w.Write(message)

			if err := w.Close(); err != nil {
				return
			}
		case <-ticker.C:
			if err := o.Conn.SetWriteDeadline(time.Now().Add(writeWait)); err != nil {
				return
			}
			if err := o.Conn.WriteMessage(websocket.PingMessage, nil); err != nil {
				return
			}
		}
	}
}
