package knowledgeqa

import (
	"errors"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
)

func (handler *feedbackHandler) Upsert(
	request api.WorkspaceScopedJSON[dto.KnowledgeQAFeedbackRequest],
) (api.Response, error) {
	sessionID := routeParameter(request.Gin, "sessionId")
	turnID := routeParameter(request.Gin, "turnId")
	if sessionID == "" || turnID == "" {
		return api.Response{}, invalidRequest("sessionId and turnId are required")
	}
	if handler.deps.Feedbacks == nil {
		return api.Response{}, errors.New("Knowledge Q&A feedback service is unavailable")
	}
	snapshot, err := handler.deps.Sessions.LoadFeedbackSnapshotForOwner(
		request.Context(), request.WorkspaceID(), request.UserID(), sessionID, turnID,
	)
	if err != nil {
		return storeFailure(err)
	}
	feedback, err := handler.deps.Feedbacks.UpsertFeedback(
		request.Context(),
		UpsertFeedbackParams{
			Snapshot:       snapshot,
			ReporterUserID: request.UserID(),
			Rating:         request.Body.Rating,
			Reasons:        request.Body.Reasons,
			Comment:        request.Body.Comment,
			Now:            time.Now().UTC(),
		},
	)
	if err != nil {
		if errors.Is(err, ErrFeedbackInvalid) {
			return api.Response{}, invalidRequest("Knowledge Q&A feedback is invalid")
		}
		return api.Response{}, err
	}
	return api.OK(dto.KnowledgeQAFeedbackResponse{
		Feedback: toFeedbackDTO(feedback),
	}), nil
}

func (handler *feedbackHandler) Delete(
	request api.WorkspaceScopedRequest,
) (api.Response, error) {
	sessionID := routeParameter(request.Gin, "sessionId")
	turnID := routeParameter(request.Gin, "turnId")
	if sessionID == "" || turnID == "" {
		return api.Response{}, invalidRequest("sessionId and turnId are required")
	}
	if handler.deps.Feedbacks == nil {
		return api.Response{}, errors.New("Knowledge Q&A feedback service is unavailable")
	}
	if _, err := handler.deps.Sessions.LoadFeedbackSnapshotForOwner(
		request.Context(), request.WorkspaceID(), request.UserID(), sessionID, turnID,
	); err != nil {
		return storeFailure(err)
	}
	if err := handler.deps.Feedbacks.DeleteFeedback(
		request.Context(), request.WorkspaceID(), request.UserID(), turnID,
	); err != nil {
		return api.Response{}, err
	}
	return api.OK(dto.KnowledgeQAFeedbackDeleteResponse{OK: true}), nil
}

func toFeedbackDTO(feedback Feedback) dto.KnowledgeQAFeedback {
	return dto.KnowledgeQAFeedback{
		ID:        feedback.ID,
		Rating:    feedback.Rating,
		Reasons:   nonNilStrings(feedback.Reasons),
		Comment:   feedback.Comment,
		UpdatedAt: feedback.UpdatedAt,
	}
}
