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"
)

// Get handles GET /api/tasks/channel/:channelId/view-state.
// It returns the saved view state for a channel's task board.
func (handler *BoardViewStateHandler) Get(r api.WorkspaceScopedRequest) (api.Response, error) {
	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")
	}

	response, err := handler.taskBoard.GetTaskBoardViewState(r.Context(), GetTaskBoardViewStateRequest{
		Context: NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Board:   BoardRef{ChannelID: channelID},
	})
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToTaskBoardViewStateResponse(taskboardGetTaskBoardViewStateResponseForDTO(response))), nil
}

// Set handles PUT /api/tasks/channel/:channelId/view-state.
// It saves or replaces the view state for a channel's task board.
func (handler *BoardViewStateHandler) Set(r api.WorkspaceScopedJSON[dto.TaskBoardViewStateRequest]) (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")
	}

	response, err := handler.taskBoard.PutTaskBoardViewState(r.Context(), PutTaskBoardViewStateRequest{
		Context:   NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Board:     BoardRef{ChannelID: channelID},
		ViewState: taskBoardViewStateForPort(converter.FromTaskBoardViewState(request)),
	})
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToTaskBoardViewStatePutResponse(taskboardPutTaskBoardViewStateResponseForDTO(response))), nil
}

// ListSavedViews handles GET /api/task-board/saved-views.
// It returns the current user's workspace-level saved task-board views.
func (handler *BoardViewStateHandler) ListSavedViews(r api.WorkspaceScopedRequest) (api.Response, error) {
	authenticated := r.User
	workspaceID := r.WorkspaceID()

	response, err := handler.taskBoard.ListTaskBoardSavedViews(r.Context(), ListTaskBoardSavedViewsRequest{
		Context: NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
	})
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToTaskBoardSavedViewsResponse(taskboardListTaskBoardSavedViewsResponseForDTO(response))), nil
}

// CreateSavedView handles POST /api/task-board/saved-views.
// It saves the current user's named workspace-level task-board view.
func (handler *BoardViewStateHandler) CreateSavedView(r api.WorkspaceScopedJSON[dto.TaskBoardSavedViewRequest]) (api.Response, error) {
	request := r.Body
	authenticated := r.User
	workspaceID := r.WorkspaceID()

	response, err := handler.taskBoard.CreateTaskBoardSavedView(r.Context(), CreateTaskBoardSavedViewRequest{
		Context:   NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		Name:      request.Name,
		ViewState: taskBoardViewStateForPort(converter.FromTaskBoardViewState(request.ViewState)),
	})
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToTaskBoardSavedViewCreateResponse(taskboardCreateTaskBoardSavedViewResponseForDTO(response))), nil
}

// UpdateSavedView handles PATCH /api/task-board/saved-views/:savedViewId.
// It replaces the current user's saved view name and state.
func (handler *BoardViewStateHandler) UpdateSavedView(r api.WorkspaceScopedJSON[dto.TaskBoardSavedViewRequest]) (api.Response, error) {
	request := r.Body
	authenticated := r.User
	workspaceID := r.WorkspaceID()

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

	response, err := handler.taskBoard.UpdateTaskBoardSavedView(r.Context(), UpdateTaskBoardSavedViewRequest{
		Context:     NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		SavedViewID: savedViewID,
		Name:        request.Name,
		ViewState:   taskBoardViewStateForPort(converter.FromTaskBoardViewState(request.ViewState)),
	})
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToTaskBoardSavedViewUpdateResponse(taskboardUpdateTaskBoardSavedViewResponseForDTO(response))), nil
}

// DeleteSavedView handles DELETE /api/task-board/saved-views/:savedViewId.
// It deletes one saved view owned by the current user.
func (handler *BoardViewStateHandler) DeleteSavedView(r api.WorkspaceScopedRequest) (api.Response, error) {
	authenticated := r.User
	workspaceID := r.WorkspaceID()

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

	_, err := handler.taskBoard.DeleteTaskBoardSavedView(r.Context(), DeleteTaskBoardSavedViewRequest{
		Context:     NewUserServiceContext(workspaceID, authenticated.User.ID, authenticated.User.Name),
		SavedViewID: savedViewID,
	})
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(map[string]any{}), nil
}
