package binding

import (
	"net/http"

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

func (handler *DetailHandler) Get(request api.WorkspaceScopedRequest) (api.Response, error) {
	id, err := bindingID(request)
	if err != nil {
		return api.Response{}, err
	}
	binding, err := handler.service.Get(request.Context(), request.WorkspaceID(), id)
	if err != nil {
		return api.Response{}, err
	}
	return bindingOK(binding), nil
}

func (handler *DetailHandler) Update(request api.WorkspaceScopedJSON[dto.WorkflowBindingUpdateRequest]) (api.Response, error) {
	id, expectedRevision, err := bindingMutationPreconditions(request.WorkspaceScopedRequest)
	if err != nil {
		return api.Response{}, err
	}
	idempotencyKey, err := requireIdempotencyKey(request.Gin.GetHeader(idempotencyHeader))
	if err != nil {
		return api.Response{}, err
	}
	binding, err := handler.service.UpdateMetadata(request.Context(), UpdateMetadataInput{
		WorkspaceID:      request.WorkspaceID(),
		BindingID:        id,
		ExpectedRevision: expectedRevision,
		DisplayName:      request.Body.DisplayName,
		DescriptionMD:    request.Body.DescriptionMD,
		Principal:        requestOwner(request.WorkspaceScopedRequest),
		Actor:            requestActor(request.WorkspaceScopedRequest),
		IdempotencyKey:   idempotencyKey,
	})
	if err != nil {
		return api.Response{}, err
	}
	return bindingOK(binding), nil
}

func (handler *DetailHandler) Disable(request api.WorkspaceScopedRequest) (api.Response, error) {
	return handler.changeLifecycle(request, "disable")
}

func (handler *DetailHandler) Archive(request api.WorkspaceScopedRequest) (api.Response, error) {
	return handler.changeLifecycle(request, "archive")
}

func (handler *DetailHandler) Restore(request api.WorkspaceScopedRequest) (api.Response, error) {
	return handler.changeLifecycle(request, "restore")
}

func (handler *DetailHandler) changeLifecycle(request api.WorkspaceScopedRequest, operation string) (api.Response, error) {
	id, expectedRevision, err := bindingMutationPreconditions(request)
	if err != nil {
		return api.Response{}, err
	}
	idempotencyKey, err := requireIdempotencyKey(request.Gin.GetHeader(idempotencyHeader))
	if err != nil {
		return api.Response{}, err
	}
	input := LifecycleInput{
		WorkspaceID:      request.WorkspaceID(),
		BindingID:        id,
		ExpectedRevision: expectedRevision,
		Principal:        requestOwner(request),
		Actor:            requestActor(request),
		IdempotencyKey:   idempotencyKey,
	}
	var binding Binding
	switch operation {
	case "disable":
		binding, err = handler.service.Disable(request.Context(), input)
	case "archive":
		binding, err = handler.service.Archive(request.Context(), input)
	case "restore":
		binding, err = handler.service.Restore(request.Context(), input)
	default:
		return api.Response{}, publicError(http.StatusInternalServerError, "binding_internal_error", "unsupported Binding lifecycle operation")
	}
	if err != nil {
		return api.Response{}, err
	}
	return bindingOK(binding), nil
}

func bindingOK(binding Binding) api.Response {
	return api.Response{Status: http.StatusOK, Body: bindingResponse(binding), Headers: http.Header{"ETag": []string{bindingETag(binding.ID, binding.Revision)}}}
}
