package api

import (
	"context"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"

	"github.com/rycroftapparel/workpulse-api/internal/httpapi"
	"github.com/rycroftapparel/workpulse-api/internal/realtime"
)

func (s *Server) postWSTicket(c *gin.Context) {
	uid := userID(c)
	t, err := s.Hub.IssueTicket(uid, s.Cfg.WSTicketTTL)
	if err != nil {
		c.JSON(http.StatusInternalServerError, httpapi.Fail("ticket", err.Error()))
		return
	}
	c.JSON(http.StatusOK, httpapi.OK(gin.H{
		"ticket":    t,
		"expiresIn": int(s.Cfg.WSTicketTTL.Seconds()),
		"path":      "/api/v1/ws",
	}))
}

func (s *Server) getWS(c *gin.Context) {
	ticket := strings.TrimSpace(c.Query("ticket"))
	if ticket == "" {
		c.JSON(http.StatusBadRequest, httpapi.Fail("validation", "missing ticket query param"))
		return
	}
	uid, ok := s.Hub.ConsumeTicket(ticket)
	if !ok {
		c.JSON(http.StatusUnauthorized, httpapi.Fail("invalid_ticket", "invalid or expired ticket"))
		return
	}
	up := websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			o := r.Header.Get("Origin")
			if o == "" {
				return true
			}
			for _, a := range s.Cfg.CORSOrigins {
				if o == a {
					return true
				}
			}
			return false
		},
	}
	conn, err := up.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		return
	}
	isMember := func(teamID uint64) bool {
		ctx, cancel := context.WithTimeout(context.Background(), s.Cfg.QueryTimeout)
		defer cancel()
		ok, err := s.IsTeamMember(ctx, uid, teamID)
		return err == nil && ok
	}
	realtime.RunPeer(s.Hub, uid, conn, isMember)
}
