package workspace

import (
	"net/http"

	"github.com/gin-gonic/gin"

	wsapi "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/ticket-manager/workspace"
	apiutils "github.com/tidbcloud/aisupport/packages/sdk-go/infra/apiserver/utils"
	"github.com/tidbcloud/aisupport/packages/sdk-go/infra/errs"
	workspacesvcapi "github.com/tidbcloud/aisupport/services/ticket-manager/internal/services/workspace/api"
)

// ListAdvices lists workspace advices.
//
//	@Summary	List workspace advices
//	@Id			WorkspaceHandlerListAdvices
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		param	query		wsapi.ListAdvicesRequest	false	"param"
//	@Success	200		{object}	wsapi.ListAdvicesResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices [get]
func (h *Handler) ListAdvices(c *gin.Context) {
	var req wsapi.ListAdvicesRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	param := workspacesvcapi.ListAdvicesParam{
		TypeIn:   req.Type,
		StatusIn: req.Status,
		Page: &workspacesvcapi.PageParam{
			Page:     int(req.Page),
			PageSize: int(req.PageSize),
		},
	}
	if req.WorkspaceID != 0 {
		param.WorkspaceIDIs = &req.WorkspaceID
	}

	advices, total, err := h.Workspace.ListAdvices(c, param)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.ListAdvicesResponse{
		Advices: advices,
		Total:   total,
	})
}

// GetAdvice gets a workspace advice.
//
//	@Summary	Get workspace advice
//	@Id			WorkspaceHandlerGetAdvice
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int	true	"Advice ID"
//	@Success	200		{object}	wsapi.GetAdviceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices/{id} [get]
func (h *Handler) GetAdvice(c *gin.Context) {
	adviceID, err := parseUintParam(c, "id")
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	advice, err := h.Workspace.GetAdvice(c, adviceID)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.GetAdviceResponse{
		Advice: advice,
	})
}

// CreateAdvice creates a workspace advice.
//
//	@Summary	Create workspace advice
//	@Id			WorkspaceHandlerCreateAdvice
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		request	body		wsapi.CreateAdviceRequest	true	"Workspace advice payload"
//	@Success	200		{object}	wsapi.CreateAdviceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices [post]
func (h *Handler) CreateAdvice(c *gin.Context) {
	var req wsapi.CreateAdviceRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	advice, err := h.Workspace.CreateAdvice(c, workspacesvcapi.CreateAdviceParam{
		WorkspaceID:    req.WorkspaceID,
		Description:    req.Description,
		Type:           req.Type,
		Data:           req.Data,
		ReplyMessageID: req.ReplyMessageID,
	})
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.CreateAdviceResponse{
		Advice: advice,
	})
}

// UpdateAdvice updates a workspace advice.
//
//	@Summary	Update workspace advice
//	@Id			WorkspaceHandlerUpdateAdvice
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int							true	"Advice ID"
//	@Param		request	body		wsapi.UpdateAdviceRequest	true	"Workspace advice payload"
//	@Success	200		{object}	wsapi.UpdateAdviceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices/{id} [put]
func (h *Handler) UpdateAdvice(c *gin.Context) {
	adviceID, err := parseUintParam(c, "id")
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	var req wsapi.UpdateAdviceRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	advice, err := h.Workspace.UpdateAdvice(c, adviceID, workspacesvcapi.UpdateAdviceParam{
		Description: req.Description,
		Data:        req.Data,
	})
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.UpdateAdviceResponse{
		Advice: advice,
	})
}

// ApplyAdvice applies a workspace advice.
//
//	@Summary	Apply workspace advice
//	@Id			WorkspaceHandlerApplyAdvice
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int	true	"Advice ID"
//	@Success	200		{object}	wsapi.ApplyAdviceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices/{id}/apply [post]
func (h *Handler) ApplyAdvice(c *gin.Context) {
	adviceID, err := parseUintParam(c, "id")
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	advice, err := h.Workspace.ApplyAdvice(c, adviceID)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.ApplyAdviceResponse{
		Advice: advice,
	})
}

// IgnoreAdvice ignores a workspace advice.
//
//	@Summary	Ignore workspace advice
//	@Id			WorkspaceHandlerIgnoreAdvice
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int	true	"Advice ID"
//	@Success	200		{object}	wsapi.IgnoreAdviceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices/{id}/ignore [post]
func (h *Handler) IgnoreAdvice(c *gin.Context) {
	adviceID, err := parseUintParam(c, "id")
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	advice, err := h.Workspace.IgnoreAdvice(c, adviceID)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.IgnoreAdviceResponse{
		Advice: advice,
	})
}

// DeleteAdvice deletes a workspace advice.
//
//	@Summary	Delete workspace advice
//	@Id			WorkspaceHandlerDeleteAdvice
//	@Tags		WorkspaceHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int	true	"Advice ID"
//	@Success	200		{object}	wsapi.DeleteAdviceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/workspace/advices/{id} [delete]
func (h *Handler) DeleteAdvice(c *gin.Context) {
	adviceID, err := parseUintParam(c, "id")
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	advice, err := h.Workspace.DeleteAdvice(c, adviceID)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &wsapi.DeleteAdviceResponse{
		Advice: advice,
	})
}
