package push

import (
	"encoding/json"
	"net/http"

	"github.com/TaruLab/keluargamart-backend/internal/auth"
	"github.com/TaruLab/keluargamart-backend/pkg/httpresponse"
	"github.com/TaruLab/keluargamart-backend/pkg/middleware"
)

type Handler struct {
	svc *Service
}

func NewHandler(svc *Service) *Handler {
	return &Handler{svc: svc}
}

func (h *Handler) Subscribe(w http.ResponseWriter, r *http.Request) {
	u := auth.UserFrom(r.Context())
	if u == nil {
		httpresponse.Error(w, http.StatusUnauthorized, middleware.RequestIDFrom(r.Context()),
			httpresponse.CodeAuthentication, "Authentication required", nil)
		return
	}

	var in SubscribeInput
	if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
		httpresponse.Error(w, http.StatusBadRequest, middleware.RequestIDFrom(r.Context()),
			httpresponse.CodeValidation, "Invalid request payload", nil)
		return
	}

	sub, err := h.svc.Subscribe(r.Context(), u.ID, in, r.UserAgent())
	if err != nil {
		httpresponse.Error(w, http.StatusBadRequest, middleware.RequestIDFrom(r.Context()),
			httpresponse.CodeValidation, err.Error(), nil)
		return
	}

	httpresponse.OK(w, http.StatusOK, middleware.RequestIDFrom(r.Context()), sub)
}

func (h *Handler) Unsubscribe(w http.ResponseWriter, r *http.Request) {
	u := auth.UserFrom(r.Context())
	if u == nil {
		httpresponse.Error(w, http.StatusUnauthorized, middleware.RequestIDFrom(r.Context()),
			httpresponse.CodeAuthentication, "Authentication required", nil)
		return
	}

	var in struct {
		Endpoint string `json:"endpoint"`
	}
	_ = json.NewDecoder(r.Body).Decode(&in)

	if in.Endpoint != "" {
		_ = h.svc.Unsubscribe(r.Context(), u.ID, in.Endpoint)
	}

	httpresponse.OK(w, http.StatusOK, middleware.RequestIDFrom(r.Context()), map[string]any{"success": true})
}

func (h *Handler) TestPush(w http.ResponseWriter, r *http.Request) {
	u := auth.UserFrom(r.Context())
	if u == nil {
		httpresponse.Error(w, http.StatusUnauthorized, middleware.RequestIDFrom(r.Context()),
			httpresponse.CodeAuthentication, "Authentication required", nil)
		return
	}

	sent := h.svc.SendToUser(r.Context(), u.ID, Payload{
		Title: "Uji Notifikasi Latar Belakang",
		Body:  "Background push notification KeluargaMart aktif dan berfungsi normal.",
		Icon:  "/icons/icon-192x192.png",
		Badge: "/favicon.svg",
		Sound: "/sounds/notification.mp3",
		URL:   "/dashboard",
	})

	httpresponse.OK(w, http.StatusOK, middleware.RequestIDFrom(r.Context()), map[string]any{
		"message": "Push notification sent",
		"devices": sent,
	})
}

func (h *Handler) VapidKey(w http.ResponseWriter, r *http.Request) {
	httpresponse.OK(w, http.StatusOK, middleware.RequestIDFrom(r.Context()), map[string]any{
		"vapid_public_key": h.svc.VapidPublicKey(),
	})
}
