package runmanage

import (
	"errors"

	"github.com/tidbcloud/AgentTeam/internal/store/storeerr"
)

type ErrorCode string

const (
	ErrorCodeInvalidRequest   ErrorCode = "run_invalid_request"
	ErrorCodeNotFound         ErrorCode = "run_not_found"
	ErrorCodeForbidden        ErrorCode = "run_forbidden"
	ErrorCodeConflict         ErrorCode = "run_conflict"
	ErrorCodeTerminalConflict ErrorCode = "run_terminal_conflict"
)

type RequestError struct {
	Kind    error
	Code    ErrorCode
	Message string
	Details any
	Cause   error
}

func (err RequestError) Error() string { return err.Message }

// Unwrap returns the declared store kind only. The declared Kind is
// authoritative for public status/code classification: the internal Cause is
// preserved separately (InternalCause) for logs and structured logging and
// never participates in the errors.Is/As graph consumed by publicerr, so an
// internal cause that itself carries a store sentinel can never override the
// declared kind.
func (err RequestError) Unwrap() error { return err.Kind }

// InternalCause returns the originating repository error retained exclusively
// for logs and wrapping, or nil. It is deliberately not part of the Unwrap
// chain.
func (err RequestError) InternalCause() error { return err.Cause }

// WorkflowPublicError implements publicerr.DomainError so the centralized
// Workflow error classifier can extract the stable code and structured details
// without importing this domain package.
func (err RequestError) WorkflowPublicError() (string, any) {
	return string(err.Code), err.Details
}

type TerminalConflictDetails struct {
	Status string `json:"status"`
}

func ErrorDetails(err error) (ErrorCode, any, bool) {
	var requestError RequestError
	if !errors.As(err, &requestError) {
		return "", nil, false
	}
	return requestError.Code, requestError.Details, true
}

func invalidRequest(message string) error {
	return RequestError{Kind: storeerr.ErrBadRequest, Code: ErrorCodeInvalidRequest, Message: message}
}

func terminalConflict(status string) error {
	return RequestError{
		Kind: storeerr.ErrConflict, Code: ErrorCodeTerminalConflict,
		Message: "completed Workflow Run cannot be canceled",
		Details: TerminalConflictDetails{Status: status},
	}
}
