// Code generated by candi v1.8.17.

package resthandler

import (
	"net/http"

	"github.com/labstack/echo"

	"monorepo/services/user-service/internal/modules/member/usecase"
	shareddomain "monorepo/services/user-service/pkg/shared/domain"

	"pkg.agungdp.dev/candi/candihelper"
	"pkg.agungdp.dev/candi/candishared"
	"pkg.agungdp.dev/candi/codebase/interfaces"
	"pkg.agungdp.dev/candi/tracer"
	"pkg.agungdp.dev/candi/wrapper"
)

// RestHandler handler
type RestHandler struct {
	mw        interfaces.Middleware
	uc        usecase.MemberUsecase
	validator interfaces.Validator
}

// NewRestHandler create new rest handler
func NewRestHandler(mw interfaces.Middleware, uc usecase.MemberUsecase, validator interfaces.Validator) *RestHandler {
	return &RestHandler{
		mw: mw, uc: uc, validator: validator,
	}
}

// Mount handler with root "/"
// handling version in here
func (h *RestHandler) Mount(root *echo.Group) {
	v1Root := root.Group(candihelper.V1)

	member := v1Root.Group("/member", echo.WrapMiddleware(h.mw.HTTPBearerAuth))
	member.GET("", h.getAllMember) //, echo.WrapMiddleware(h.mw.HTTPPermissionACL("resource.public")))
	member.GET("/:id", h.getDetailMemberByID, echo.WrapMiddleware(h.mw.HTTPPermissionACL("resource.public")))
	member.POST("", h.saveMember) //, echo.WrapMiddleware(h.mw.HTTPPermissionACL("resource.public")))
	member.GET("/me", h.getMe)
}

func (h *RestHandler) getAllMember(c echo.Context) error {
	trace := tracer.StartTrace(c.Request().Context(), "MemberDeliveryREST:GetAllMember")
	defer trace.Finish()
	ctx := trace.Context()

	tokenClaim := candishared.ParseTokenClaimFromContext(ctx) // must using HTTPBearerAuth in middleware for this handler

	var filter candishared.Filter
	if err := candihelper.ParseFromQueryParam(c.Request().URL.Query(), &filter); err != nil {
		return wrapper.NewHTTPResponse(http.StatusBadRequest, err.Error()).JSON(c.Response())
	}

	data, meta, err := h.uc.GetAllMember(ctx, filter)
	if err != nil {
		return wrapper.NewHTTPResponse(http.StatusOK, err.Error()).JSON(c.Response())
	}

	message := "Success, with your user id (" + tokenClaim.Subject + ") and role (" + tokenClaim.Role + ")"
	return wrapper.NewHTTPResponse(http.StatusOK, message, meta, data).JSON(c.Response())
}

func (h *RestHandler) getDetailMemberByID(c echo.Context) error {
	trace := tracer.StartTrace(c.Request().Context(), "MemberDeliveryREST:GetDetailMemberByID")
	defer trace.Finish()

	data, err := h.uc.GetDetailMember(trace.Context(), c.Param("id"))
	if err != nil {
		return wrapper.NewHTTPResponse(http.StatusBadRequest, err.Error()).JSON(c.Response())
	}

	return wrapper.NewHTTPResponse(http.StatusOK, "Success", data).JSON(c.Response())
}

func (h *RestHandler) saveMember(c echo.Context) error {
	trace := tracer.StartTrace(c.Request().Context(), "AppsDeliveryREST:SaveMember")
	defer trace.Finish()

	var payload shareddomain.Member
	if err := c.Bind(&payload); err != nil {
		return wrapper.NewHTTPResponse(http.StatusOK, err.Error()).JSON(c.Response())
	}

	err := h.uc.SaveMember(trace.Context(), &payload)
	if err != nil {
		return wrapper.NewHTTPResponse(http.StatusBadRequest, err.Error()).JSON(c.Response())
	}

	return wrapper.NewHTTPResponse(http.StatusOK, "Success").JSON(c.Response())
}

func (h *RestHandler) getMe(c echo.Context) error {
	trace := tracer.StartTrace(c.Request().Context(), "MemberDeliveryREST:GetMe")
	defer trace.Finish()
	ctx := trace.Context()

	tokenClaim := candishared.ParseTokenClaimFromContext(ctx) // must using HTTPBearerAuth in middleware for this handler

	data, err := h.uc.GetDetailMember(ctx, tokenClaim.Subject)
	if err != nil {
		return wrapper.NewHTTPResponse(http.StatusBadRequest, err.Error()).JSON(c.Response())
	}

	return wrapper.NewHTTPResponse(http.StatusOK, "Success", data).JSON(c.Response())
}
