package commerce

import (
	"errors"
	"log/slog"
	"net/http"

	"github.com/go-chi/chi/v5"

	"qycw/go-server/internal/response"
)

type Handler struct {
	service *Service
	logger  *slog.Logger
}

func NewHandler(service *Service, logger *slog.Logger) *Handler {
	return &Handler{service: service, logger: logger}
}

func (h *Handler) Routes() http.Handler {
	r := chi.NewRouter()
	r.Get("/categories", h.listCategories)
	r.Get("/categories/{cat_slug}/groups", h.listGroups)
	r.Get("/categories/{cat_slug}/groups/{group_slug}/products", h.listProducts)
	return r
}

func (h *Handler) listCategories(w http.ResponseWriter, r *http.Request) {
	data, err := h.service.ListCategories(r.Context())
	h.writeResult(w, data, err)
}

func (h *Handler) listGroups(w http.ResponseWriter, r *http.Request) {
	data, err := h.service.ListGroups(r.Context(), chi.URLParam(r, "cat_slug"))
	h.writeResult(w, data, err)
}

func (h *Handler) listProducts(w http.ResponseWriter, r *http.Request) {
	data, err := h.service.ListProducts(r.Context(), chi.URLParam(r, "cat_slug"), chi.URLParam(r, "group_slug"))
	h.writeResult(w, data, err)
}

func (h *Handler) writeResult(w http.ResponseWriter, data any, err error) {
	if err != nil {
		h.writeError(w, err)
		return
	}
	response.OK(w, data)
}

func (h *Handler) writeError(w http.ResponseWriter, err error) {
	var httpErr HTTPError
	if errors.As(err, &httpErr) {
		response.Detail(w, httpErr.Status, httpErr.Detail)
		return
	}
	if h.logger != nil {
		h.logger.Error("commerce handler error", "error", err)
	}
	response.Detail(w, http.StatusInternalServerError, msgServiceError)
}
