package gateway

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

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

	"nexavpn/backend/internal/apiutil"
)

type Handler struct {
	service        *Service
	bootstrapToken string
}

func NewHandler(service *Service, bootstrapToken string) *Handler {
	return &Handler{service: service, bootstrapToken: bootstrapToken}
}

func (h *Handler) List(w http.ResponseWriter, r *http.Request) {
	items, err := h.service.List(r.Context())
	if err != nil {
		apiutil.Error(w, http.StatusInternalServerError, "gateways_list_failed", "unable to list gateways")
		return
	}

	apiutil.JSON(w, http.StatusOK, items)
}

func (h *Handler) SyncBundle(w http.ResponseWriter, r *http.Request) {
	bundle, err := h.service.BuildSyncBundle(r.Context(), chi.URLParam(r, "id"))
	if err != nil {
		apiutil.Error(w, http.StatusBadRequest, "gateway_sync_failed", "unable to build sync bundle")
		return
	}

	apiutil.JSON(w, http.StatusOK, bundle)
}

func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
	var input UpdateRequest
	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
		apiutil.Error(w, http.StatusBadRequest, "invalid_json", "invalid request body")
		return
	}

	item, err := h.service.Update(r.Context(), chi.URLParam(r, "id"), input)
	if err != nil {
		apiutil.Error(w, http.StatusBadRequest, "gateway_update_failed", "unable to update gateway")
		return
	}

	apiutil.JSON(w, http.StatusOK, item)
}

func (h *Handler) Bootstrap(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("X-Gateway-Bootstrap-Token") != h.bootstrapToken {
		apiutil.Error(w, http.StatusUnauthorized, "unauthorized", "invalid gateway bootstrap token")
		return
	}

	var input BootstrapRequest
	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
		apiutil.Error(w, http.StatusBadRequest, "invalid_json", "invalid request body")
		return
	}

	item, err := h.service.Bootstrap(r.Context(), input)
	if err != nil {
		apiutil.Error(w, http.StatusBadRequest, "gateway_bootstrap_failed", "unable to bootstrap gateway")
		return
	}

	apiutil.JSON(w, http.StatusOK, item)
}

func (h *Handler) AgentSyncBundle(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("X-Gateway-Bootstrap-Token") != h.bootstrapToken {
		apiutil.Error(w, http.StatusUnauthorized, "unauthorized", "invalid gateway bootstrap token")
		return
	}

	bundle, err := h.service.BuildSyncBundle(r.Context(), chi.URLParam(r, "id"))
	if err != nil {
		apiutil.Error(w, http.StatusBadRequest, "gateway_sync_failed", "unable to build sync bundle")
		return
	}

	apiutil.JSON(w, http.StatusOK, bundle)
}
