package transport

import (
	"rpirelay/internal/api/relay"

	cc "rpirelay/internal/context"
	apierr "rpirelay/internal/errors"

	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
)

type HTTP struct {
	svc relay.Service
}

func NewHTTP(svc relay.Service, e *gin.RouterGroup, authorizationMW cc.CustomHandler) {
	h := &HTTP{svc: svc}
	patch := cc.PatchContext

	g := e.Group("/relay")
	g.Use(patch(authorizationMW))

	// swagger:route POST /api/relay/on relay switchOn
	// set relay on
	// security:
	//  api_key:
	// responses:
	//  default: respDefault
	g.POST("/on", patch(h.switchOn()))

	// swagger:route POST /api/relay/off relay switchOff
	// set relay off
	// security:
	//  api_key:
	// responses:
	//  default: respDefault
	g.POST("/off", patch(h.switchOff()))

	// swagger:route GET /api/relay relay getState
	// get relay state
	// security:
	//  api_key:
	// responses:
	//  200: relayStateResp
	//  default: respDefault
	g.GET("/", patch(h.getState()))
	g.GET("", patch(h.getState()))
}

func (h *HTTP) switchOn() cc.CustomHandler {
	return func(c *cc.C) {
		if err := h.svc.SwitchOn(c); err != nil {
			panic(apierr.ErrInternalError.SetErr(errors.WithStack(err)))
		}

		c.Success()
	}
}

func (h *HTTP) switchOff() cc.CustomHandler {
	return func(c *cc.C) {
		if err := h.svc.SwitchOff(c); err != nil {
			panic(apierr.ErrInternalError.SetErr(errors.WithStack(err)))
		}

		c.Success()
	}
}

type relayStateResp struct {
	Open bool `json:"open"`
}

func (h *HTTP) getState() cc.CustomHandler {
	return func(c *cc.C) {
		open, err := h.svc.GetState(c)
		if err != nil {
			panic(apierr.ErrInternalError.SetErr(errors.WithStack(err)))
		}

		resp := relayStateResp{Open: open}

		c.Success(resp)
	}
}
