package knowledgeqa

import (
	"context"
	"errors"
	"net/http"
	"time"

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

func (handler *sessionHandler) CreateSession(
	request api.WorkspaceScopedJSON[dto.KnowledgeQACreateSessionRequest],
) (api.Response, error) {
	if err := validateCreateSessionRequest(request.Body); err != nil {
		return api.Response{}, err
	}
	idempotencyKey, err := requireIdempotencyKey(request.Gin)
	if err != nil {
		return api.Response{}, err
	}
	organizationSummary, effective, err := handler.resolveSubmissionPolicy(
		request.Context(), request.UserID(), request.WorkspaceID(),
		request.Body.Model, request.Body.ReasonLevel,
	)
	if err != nil {
		return api.Response{}, err
	}
	now := time.Now().UTC()
	session, err := handler.deps.Sessions.CreateSession(request.Context(), CreateSessionParams{
		ID:                        request.Body.SessionID,
		WorkspaceID:               request.WorkspaceID(),
		OrganizationID:            organizationSummary.ID,
		OwnerUserID:               request.UserID(),
		OwnerMemberID:             request.Workspace.MemberID,
		RootMessageID:             request.Body.RootMessageID,
		ThreadChannelID:           request.Body.ThreadChannelID,
		RequestedKnowledgeBaseIDs: request.Body.KnowledgeBaseIDs,
		RequestedSourceIDs:        request.Body.SourceIDs,
		RequestedModel:            effective.Model,
		RequestedReasonLevel:      effective.ReasonLevel,
		WebSearchEnabled:          request.Body.WebSearchEnabled,
		Now:                       now,
	})
	if err != nil {
		return storeFailure(err)
	}
	turn, err := handler.deps.Sessions.CreateTurn(
		context.WithoutCancel(request.Context()),
		CreateTurnParams{
			WorkspaceID:               session.WorkspaceID,
			OrganizationID:            session.OrganizationID,
			SessionID:                 session.ID,
			RequesterUserID:           session.OwnerUserID,
			UserMessageID:             request.Body.UserMessageID,
			Question:                  request.Body.Question,
			IdempotencyKey:            idempotencyKey,
			RequestedKnowledgeBaseIDs: request.Body.KnowledgeBaseIDs,
			RequestedSourceIDs:        request.Body.SourceIDs,
			Now:                       now,
		},
	)
	if err != nil {
		return storeFailure(err)
	}
	handler.notifyTurnUpdated(
		request.Context(), session.WorkspaceID, session.OwnerMemberID, session.ThreadChannelID, turn.ID,
	)
	handler.notifyQueued(turn)
	return api.Response{
		Status: http.StatusAccepted,
		Body: dto.KnowledgeQASessionResponse{
			Session: toSessionDTO(session),
			Turn:    toTurnDTO(turn),
		},
	}, nil
}

func (handler *sessionHandler) DeleteThread(request api.WorkspaceScopedRequest) (api.Response, error) {
	threadID := routeParameter(request.Gin, "threadId")
	if threadID == "" {
		return api.Response{}, invalidRequest("threadId is required")
	}
	session, err := handler.deps.Sessions.DeleteSessionConversationForOwner(
		request.Context(), request.WorkspaceID(), request.UserID(), threadID,
		time.Now().UTC(),
	)
	if errors.Is(err, ErrConversationNotFound) {
		return api.NoContent(), nil
	}
	if err != nil {
		return storeFailure(err)
	}
	if handler.deps.Queue != nil && session.ActiveTurnID != "" {
		handler.deps.Queue.CancelKnowledgeQATurn(
			context.WithoutCancel(request.Context()), session.ActiveTurnID, "",
		)
	}
	return api.NoContent(), nil
}
