package collaboration

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	collabapi "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/ticket-manager/collaboration"
	apiutils "github.com/tidbcloud/aisupport/packages/sdk-go/infra/apiserver/utils"
	"github.com/tidbcloud/aisupport/packages/sdk-go/infra/errs"
	collabsvcapi "github.com/tidbcloud/aisupport/services/ticket-manager/internal/services/collaboration/api"
)

// ListResources lists collaboration resources.
//
//	@Summary	List collaboration resources
//	@Id			CollaborationHandlerListResources
//	@Tags		CollaborationHandler
//	@Accept		json
//	@Produce	json
//	@Param		param	query		collabapi.ListResourcesRequest	false	"param"
//	@Success	200		{object}	collabapi.ListResourcesResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/collaboration/resources [get]
func (h *Handler) ListResources(c *gin.Context) {
	var req collabapi.ListResourcesRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	param := collabsvcapi.ListResourcesParam{
		Page: &collabsvcapi.PageParam{
			Page:     int(req.Page),
			PageSize: int(req.PageSize),
		},
	}
	if req.TicketID != 0 {
		param.TicketIDIs = &req.TicketID
	}
	if req.ResourceType != "" {
		param.ResourceTypeIs = &req.ResourceType
	}
	if req.ResourceProvider != "" {
		param.ResourceProviderIs = &req.ResourceProvider
	}
	if req.ResourceID != "" {
		param.ResourceIDIs = &req.ResourceID
	}
	if req.ResourceName != "" {
		param.ResourceNameIs = &req.ResourceName
	}

	resources, total, err := h.Collaboration.ListResources(c, param)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &collabapi.ListResourcesResponse{
		Resources: resources,
		Total:     total,
	})
}

// CreateResource creates a collaboration resource.
//
//	@Summary	Create a collaboration resource
//	@Id			CollaborationHandlerCreateResource
//	@Tags		CollaborationHandler
//	@Accept		json
//	@Produce	json
//	@Param		request	body		collabapi.CreateResourceRequest	true	"Collaboration resource create payload"
//	@Success	200		{object}	collabapi.CreateResourceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/collaboration/resources [post]
func (h *Handler) CreateResource(c *gin.Context) {
	var req collabapi.CreateResourceRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	param := collabsvcapi.CreateResourceParam{}
	if req.LarkGroup != nil {
		param.LarkGroup = &collabsvcapi.CreateResourceForLarkGroupParam{}
		if req.LarkGroup.LinkGroup != nil {
			param.LarkGroup.LinkGroup = &collabsvcapi.LinkLarkGroupParam{
				GroupID: req.LarkGroup.LinkGroup.GroupID,
			}
		}
		if req.LarkGroup.CreateGroup != nil {
			param.LarkGroup.CreateGroup = &collabsvcapi.CreateLarkGroupParam{
				GroupName:        req.LarkGroup.CreateGroup.GroupName,
				GroupDescription: req.LarkGroup.CreateGroup.GroupDescription,
				Owner:            req.LarkGroup.CreateGroup.Owner,
				Members:          req.LarkGroup.CreateGroup.Members,
			}
		}
	}
	if req.LarkMeeting != nil {
		param.LarkMeeting = &collabsvcapi.CreateResourceForLarkMeetingParam{
			MeetingID: req.LarkMeeting.MeetingID,
		}
	}
	if req.LarkDocument != nil {
		param.LarkDocument = &collabsvcapi.CreateResourceForLarkDocumentParam{
			DocID:  req.LarkDocument.DocID,
			IsWiki: req.LarkDocument.IsWiki,
			Owner:  req.LarkDocument.Owner,
		}
	}

	resource, err := h.Collaboration.GetOrCreateResource(c, param)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &collabapi.CreateResourceResponse{
		Resource: resource,
	})
}

// GetResource gets a collaboration resource.
//
//	@Summary	Get a collaboration resource
//	@Id			CollaborationHandlerGetResource
//	@Tags		CollaborationHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int	true	"Collaboration resource ID"
//	@Success	200		{object}	collabapi.GetResourceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/collaboration/resources/{id} [get]
func (h *Handler) GetResource(c *gin.Context) {
	resourceID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	resource, err := h.Collaboration.GetResource(c, resourceID)
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &collabapi.GetResourceResponse{
		Resource: resource,
	})
}

// UpdateResource updates a collaboration resource.
//
//	@Summary	Update a collaboration resource
//	@Id			CollaborationHandlerUpdateResource
//	@Tags		CollaborationHandler
//	@Accept		json
//	@Produce	json
//	@Param		id		path		int								true	"Collaboration resource ID"
//	@Param		request	body		collabapi.UpdateResourceRequest	true	"Collaboration resource update payload"
//	@Success	200		{object}	collabapi.UpdateResourceResponse
//	@Failure	default	{object}	base.BaseResponse
//	@Router		/api/v1/ticketmanager/collaboration/resources/{id} [put]
func (h *Handler) UpdateResource(c *gin.Context) {
	resourceID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

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

	updated, err := h.Collaboration.UpdateResource(c, resourceID, collabsvcapi.UpdateResourceParam{
		Name:     req.Name,
		Link:     req.Link,
		Metadata: req.Metadata,
	})
	if err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, &collabapi.UpdateResourceResponse{
		Resource: updated,
	})
}

// DeleteResource deletes a collaboration resource.
//
//	@Summary	Delete a collaboration resource
//	@Id			CollaborationHandlerDeleteResource
//	@Tags		CollaborationHandler
//	@Accept		json
//	@Produce	json
//	@Success	200		{object}	map[string]interface{}
//	@Failure	default	{object}	base.BaseResponse
//	@Param		id		path		int	true	"Collaboration resource ID"
//	@Router		/api/v1/ticketmanager/collaboration/resources/{id} [delete]
func (h *Handler) DeleteResource(c *gin.Context) {
	resourceID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		apiutils.Fail(c, errs.APIErrorNew(http.StatusBadRequest, err))
		return
	}

	if _, err := h.Collaboration.DeleteResource(c, resourceID); err != nil {
		apiutils.Fail(c, err)
		return
	}

	apiutils.Success(c, nil)
}
