package handlers

import (
	"context"
	"net/http"

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

// SDLCGenerateHandler handles async SDLC artifact generation endpoints.
type SDLCGenerateHandler struct {
	generateSvc *service.SDLCGenerateService
}

// NewSDLCGenerateHandler creates a new SDLC generate handler.
func NewSDLCGenerateHandler(generateSvc *service.SDLCGenerateService) *SDLCGenerateHandler {
	return &SDLCGenerateHandler{
		generateSvc: generateSvc,
	}
}

// Mount registers the generate endpoint on the router.
// Note: Uses direct route to avoid conflict with /projects/{id}/sdlc in sdlc.go.
// Creating a Route() group at /projects/{id}/sdlc/features/{slug} shadows
// the SDLCHandler's nested routes like /features/{slug}/artifacts/{type}/approve.
func (h *SDLCGenerateHandler) Mount(r api.Router) {
	r.With(auth.RequireScope(auth.ScopeProjectsExecute, auth.ScopeAdmin)).
		Post("/projects/{id}/sdlc/features/{slug}/generate", h.Generate)
}

// GenerateRequest is the request body for POST /projects/{id}/sdlc/features/{slug}/generate.
type GenerateRequest struct {
	// ArtifactType is the type of artifact to generate: spec, design, tasks, code, qa
	ArtifactType string `json:"artifact_type"`

	// TaskID is the specific task to implement (required for artifact_type: "code")
	TaskID string `json:"task_id,omitempty"`

	// Provider specifies which code agent to use (optional)
	Provider string `json:"provider,omitempty"`
}

// Generate handles POST /projects/{id}/sdlc/features/{slug}/generate.
// It enqueues an async task to generate an SDLC artifact.
func (h *SDLCGenerateHandler) Generate(w http.ResponseWriter, r *http.Request) {
	projectID := chi.URLParam(r, "id")
	featureSlug := chi.URLParam(r, "slug")

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

	// Validate artifact_type
	if req.ArtifactType == "" {
		api.WriteBadRequest(w, r, "artifact_type is required")
		return
	}
	if !domain.IsValidGenerateArtifactType(req.ArtifactType) {
		api.WriteBadRequest(w, r, "invalid artifact_type: must be one of spec, design, tasks, code, qa")
		return
	}

	// Validate task_id is provided for code generation
	if req.ArtifactType == "code" && req.TaskID == "" {
		api.WriteBadRequest(w, r, "task_id is required for artifact_type: code")
		return
	}

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

	result, err := h.generateSvc.GenerateArtifact(ctx, projectID, featureSlug, &domain.SDLCGenerateRequest{
		ArtifactType: req.ArtifactType,
		TaskID:       req.TaskID,
		Provider:     req.Provider,
	})
	if err != nil {
		writeSDLCError(w, r, err)
		return
	}

	api.WriteJSON(w, r, http.StatusAccepted, result)
}
