package channel

import (
	"net/http"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/store/agent"
)

// loadThreadReview resolves the review context bound to a reply thread. When
// contextId is provided via the query string it selects that specific review
// context. Handlers that carry the context id in the request body (the batch
// endpoint, which POSTs JSON) must call loadThreadReviewWithContext instead
// so the body's contextId is honored.
func (h *ThreadHandler) loadThreadReview(r api.WorkspaceScopedRequest) (agent.ReviewContext, error) {
	return h.loadThreadReviewWithContext(r, strings.TrimSpace(r.Gin.Query("contextId")))
}

// loadThreadReviewWithContext resolves the review context bound to a reply
// thread, using the caller-supplied contextID (which may originate from the
// query string or the JSON body). An empty contextID selects the first
// context bound to the thread.
func (h *ThreadHandler) loadThreadReviewWithContext(r api.WorkspaceScopedRequest, contextID string) (agent.ReviewContext, error) {
	if h.reviewStore == nil {
		return agent.ReviewContext{}, api.NewHTTPError(http.StatusInternalServerError, "Internal server error")
	}
	threadChannelID := strings.TrimSpace(r.Gin.Param("threadChannelId"))
	if threadChannelID == "" {
		return agent.ReviewContext{}, api.NewHTTPError(http.StatusBadRequest, "threadChannelId is required")
	}
	contexts, err := h.reviewStore.ListReviewContextsForThread(r.Context(), r.UserID(), r.WorkspaceID(), threadChannelID)
	if err != nil {
		return agent.ReviewContext{}, err
	}
	for _, rc := range contexts {
		if contextID != "" && rc.ID != contextID {
			continue
		}
		return rc, nil
	}
	return agent.ReviewContext{}, ErrNotFound
}

// threadReviewAgent returns the review context's source agent id when present.
// It is optional: summary/files/diff route by the review's machineId, so a
// thread review is reachable with zero agents as long as its machine is online.
func (h *ThreadHandler) threadReviewAgent(rc agent.ReviewContext) (string, error) {
	if h.hub == nil {
		return "", api.NewHTTPError(http.StatusServiceUnavailable, "Machine is offline")
	}
	return strings.TrimSpace(rc.SourceAgentID), nil
}

func reviewDefaultsFromQuery(r api.WorkspaceScopedRequest, review agent.ReviewContext) (string, string, string) {
	baseRef := strings.TrimSpace(r.Gin.Query("baseRef"))
	if baseRef == "" {
		baseRef = strings.TrimSpace(r.Gin.Query("compareRef"))
	}
	headRef := strings.TrimSpace(r.Gin.Query("headRef"))
	comparisonMode := strings.TrimSpace(r.Gin.Query("comparisonMode"))
	if baseRef == "" {
		baseRef = strings.TrimSpace(review.BaseRef)
	}
	if headRef == "" {
		headRef = strings.TrimSpace(review.HeadRef)
	}
	return baseRef, headRef, comparisonMode
}
