package router

import (
	"git.kolaente.de/konrad/Konfi-Castle-Kasino/pkg/broker"
	"net/http"
	"strconv"

	"git.kolaente.de/konrad/Konfi-Castle-Kasino/pkg/models"
	"github.com/labstack/echo/v4"
	"github.com/labstack/gommon/log"
)

// Handler represents a web handler which is able to do stuff
type Handler struct {
	str    func() models.Managable
	broker *broker.Broker
}

// UpdatedMessage is a message which holds updated data
type UpdatedMessage struct {
	Message string           `json:"message"`
	Data    models.Managable `json:"data"`
}

func (h *Handler) readAll(c echo.Context) (interface{}, error) {
	str := h.str()
	if err := c.Bind(str); err != nil {
		return nil, echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	asc := c.QueryParam("asc")
	data, err := str.ReadAll(asc)
	if err != nil {
		log.Error(err)
		return nil, echo.ErrInternalServerError
	}
	return data, nil
}

// ReadAll is the web handler for getting everything
func (h *Handler) ReadAll(c echo.Context) error {

	data, err := h.readAll(c)
	if err != nil {
		return err
	}
	return c.JSON(http.StatusOK, data)
}

// Create is the web handler to create
func (h *Handler) Create(c echo.Context) error {
	str := h.str()
	if err := c.Bind(str); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	err := str.Create()
	if err != nil {
		return echo.NewHTTPError(http.StatusInternalServerError, "Error.")
	}

	// Notify the broker
	broker.SendMessage(broker.Message{
		Kind: broker.KindCreate,
		Data: str,
	})

	return c.JSON(http.StatusOK, "success")
}

// Delete is the web handler to delete something
func (h *Handler) Delete(c echo.Context) error {
	str := h.str()
	if err := c.Bind(str); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	err := str.Delete()
	if err != nil {
		return echo.NewHTTPError(http.StatusInternalServerError, "Error.")
	}

	// Notify the broker
	broker.SendMessage(broker.Message{
		Kind: broker.KindDelete,
		Data: str,
	})

	return c.JSON(http.StatusOK, "success")
}

// Update is the handler to update an entry
func (h *Handler) Update(c echo.Context) error {
	str := h.str()
	if err := c.Bind(str); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	addcoins, _ := strconv.ParseInt(c.FormValue("addcoins"), 10, 64)
	err := str.Update(addcoins)
	if err != nil {
		log.Error(err)
		return echo.NewHTTPError(http.StatusBadRequest, err)
	}

	// Notify the broker
	broker.SendMessage(broker.Message{
		Kind: broker.KindUpdate,
		Data: str,
	})

	return c.JSON(http.StatusOK, UpdatedMessage{
		Message: "success",
		Data:    str,
	})

}
