package task

import (
	"net/http"
	"strings"

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

// WorkspaceTasks handles POST /api/tasks/workspace/browse.
// It returns paginated task results across all channels in the current workspace.
func (handler *BrowseHandler) WorkspaceTasks(r api.WorkspaceScopedJSON[dto.TaskBrowseRequest]) (api.Response, error) {
	request := r.Body
	authenticated := r.User
	workspaceID := r.WorkspaceID()

	taskBrowseQuery, err := converter.FromTaskBrowseQuery(request)
	if err != nil {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	query := taskBrowseQueryForPort(taskBrowseQuery)

	response, err := handler.taskBoard.BrowseWorkspaceTasks(r.Context(), BrowseWorkspaceTasksRequest{
		Context: NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Query:   query,
	})
	if err != nil {
		return api.Response{}, err
	}

	return api.OK(converter.ToTaskBrowseResponse(taskboardTaskRowBrowsePageForDTO(response))), nil
}

// WorkspaceBoard handles POST /api/tasks/workspace/board/browse.
// It returns the task board view with grouped columns across all visible channels.
func (handler *BrowseHandler) WorkspaceBoard(r api.WorkspaceScopedJSON[dto.TaskBrowseRequest]) (api.Response, error) {
	request := r.Body
	authenticated := r.User
	workspaceID := r.WorkspaceID()

	taskBrowseQuery, err := converter.FromTaskBrowseQuery(request)
	if err != nil {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	query := taskBrowseQueryForPort(taskBrowseQuery)

	response, err := handler.taskBoard.BrowseWorkspaceTaskBoard(r.Context(), BrowseWorkspaceTaskBoardRequest{
		Context: NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Query:   query,
	})
	if err != nil {
		return api.Response{}, err
	}

	return api.OK(converter.ToTaskBoardBrowseResponse(taskboardTaskBoardBrowsePageForDTO(response))), nil
}

// ChannelTasks handles POST /api/tasks/channel/:channelId/browse.
// It returns paginated task results for a specific channel.
func (handler *BrowseHandler) ChannelTasks(r api.WorkspaceScopedJSON[dto.TaskBrowseRequest]) (api.Response, error) {
	request := r.Body
	authenticated := r.User
	workspaceID := r.WorkspaceID()

	channelID := strings.TrimSpace(r.Gin.Param("channelId"))
	if channelID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "channelId is required")
	}

	taskBrowseQuery, err := converter.FromTaskBrowseQuery(request)
	if err != nil {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	query := taskBrowseQueryForPort(taskBrowseQuery)

	response, err := handler.taskBoard.BrowseChannelTasks(r.Context(), BrowseChannelTasksRequest{
		Context: NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Board:   BoardRef{ChannelID: channelID},
		Query:   query,
	})
	if err != nil {
		return api.Response{}, err
	}

	return api.OK(converter.ToTaskBrowseResponse(taskboardTaskRowBrowsePageForDTO(response))), nil
}

// ChannelBoard handles POST /api/tasks/channel/:channelId/board/browse.
// It returns the task board view with grouped columns for a specific channel.
func (handler *BrowseHandler) ChannelBoard(r api.WorkspaceScopedJSON[dto.TaskBrowseRequest]) (api.Response, error) {
	request := r.Body
	authenticated := r.User
	workspaceID := r.WorkspaceID()

	channelID := strings.TrimSpace(r.Gin.Param("channelId"))
	if channelID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "channelId is required")
	}

	taskBrowseQuery, err := converter.FromTaskBrowseQuery(request)
	if err != nil {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	query := taskBrowseQueryForPort(taskBrowseQuery)

	response, err := handler.taskBoard.BrowseTaskBoard(r.Context(), BrowseTaskBoardRequest{
		Context: NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Board:   BoardRef{ChannelID: channelID},
		Query:   query,
	})
	if err != nil {
		return api.Response{}, err
	}

	return api.OK(converter.ToTaskBoardBrowseResponse(taskboardTaskBoardBrowsePageForDTO(response))), nil
}
