package handlers

import (
	"context"
	"net/http"

	"github.com/go-chi/chi/v5"
	"github.com/orchard9/rdev/internal/domain"
	"github.com/orchard9/rdev/internal/logging"
	"github.com/orchard9/rdev/internal/service"
	"github.com/orchard9/rdev/pkg/api"
)

// SDLCCallbackHandler handles internal SDLC callback endpoints.
type SDLCCallbackHandler struct {
	callbackSvc   *service.SDLCCallbackService
	internalToken string
}

// NewSDLCCallbackHandler creates a new SDLC callback handler.
func NewSDLCCallbackHandler(callbackSvc *service.SDLCCallbackService, internalToken string) *SDLCCallbackHandler {
	return &SDLCCallbackHandler{
		callbackSvc:   callbackSvc,
		internalToken: internalToken,
	}
}

// Mount registers the internal callback endpoint on the router.
func (h *SDLCCallbackHandler) Mount(r api.Router) {
	r.Route("/internal/sdlc", func(r chi.Router) {
		r.Post("/callback", h.Callback)
	})
}

// Callback handles POST /internal/sdlc/callback.
// This is called by the work queue when a build task completes.
// The endpoint is protected by an internal token to prevent external access.
func (h *SDLCCallbackHandler) Callback(w http.ResponseWriter, r *http.Request) {
	// Verify internal token
	token := r.Header.Get("X-Internal-Token")
	if h.internalToken != "" && token != h.internalToken {
		api.WriteUnauthorized(w, r, "invalid internal token")
		return
	}

	var payload domain.SDLCCallbackPayload
	if err := api.DecodeJSON(r, &payload); err != nil {
		api.WriteBadRequest(w, r, "invalid request body")
		return
	}

	// Validate required fields
	if payload.ProjectID == "" {
		api.WriteBadRequest(w, r, "project_id is required")
		return
	}
	if payload.Feature == "" {
		api.WriteBadRequest(w, r, "feature is required")
		return
	}
	if payload.ArtifactType == "" {
		api.WriteBadRequest(w, r, "artifact_type is required")
		return
	}

	ctx, cancel := context.WithTimeout(r.Context(), TimeoutStandard)
	defer cancel()

	if err := h.callbackSvc.HandleCallback(ctx, &payload); err != nil {
		log := logging.FromContext(ctx).WithHandler("Callback")
		log.Error("SDLC callback handling failed",
			logging.FieldError, err.Error(),
			"task_id", payload.TaskID,
			logging.FieldProjectID, payload.ProjectID,
			"feature", payload.Feature,
		)
		api.WriteInternalError(w, r, "callback handling failed")
		return
	}

	api.WriteJSON(w, r, http.StatusOK, map[string]bool{"ok": true})
}
