package websocket

import (
	"fmt"
	"net/http"

	"github.com/fiskerinc/cloud-services/pkg/httpclient"
	"github.com/fiskerinc/cloud-services/pkg/jwt"
	"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
	"github.com/pkg/errors"
)

var authURL string = envtool.GetEnv("VERIFY_URL", "https://dev-auth.fiskerdps.com/auth/verify/")

// AuthEvent is the authentication message sent over websocket
type AuthEvent struct {
	Topic   string      `json:"topic"`
	Key     string      `json:"key"`
	Payload AuthPayload `json:"payload"`
}

// AuthPayload describes the payload received
type AuthPayload struct {
	Handler string   `json:"handler"`
	Data    AuthData `json:"data"`
}

// AuthData describes the data received
type AuthData struct {
	Token string `json:"token"`
}

// AuthResponse provides format for auth response
type AuthResponse struct {
	Handler string           `json:"handler"`
	Data    AuthResponseData `json:"data"`
}

// AuthResponseData provides data for auth response
type AuthResponseData struct {
	Authenticated bool `json:"authenticated"`
}

// AuthenticateRequest checks for valid authentication message
func AuthenticateRequest(ae AuthEvent) (bool, error) {
	if ae.Topic != "auth_service" || len(ae.Key) == 0 {
		return false, errors.New("incorrect format")
	}

	switch ae.Payload.Handler {
	case "verify":
		return verifyToken(ae.Payload.Data)
	}

	return false, errors.New("invalid request")
}

func verifyToken(ad AuthData) (bool, error) {
	tokenString := []string{fmt.Sprintf("bearer %s", ad.Token)}

	resp, err := httpclient.Get(authURL, http.Header{"authorization": tokenString})
	if err != nil {
		return false, errors.WithStack(err)
	}

	return resp.StatusCode == 200, nil
}

func parseIDFromToken(token string) (string, error) {
	payload, err := jwt.GetPayload(token)
	if err != nil {
		return fmt.Sprintf("%+v", payload), err
	}
	return fmt.Sprintf("%+v", payload), nil
}
