// Package approvalapp connects generic Approval instances and existing
// approval-shaped business authorities to AgentTeam's built-in App Notification
// transport without replacing their source-of-truth state machines.
package approvalapp

import "strings"

const (
	IdentityID           = "agentteam.approval"
	DefinitionID         = "svcdef_agentteam_approval"
	DefinitionSlug       = "agentteam-approval"
	AvatarURL            = "/builtin-apps/approval.svg"
	HandlerKey           = "agentteam.approval"
	BusinessNamespace    = "agentteam.approval"
	BusinessTypeInstance = "approval_instance"
	// BusinessTypeWorkflowRunApproval is a distinct Approval App business
	// object. Its durable authority is workflow_run_effects plus the Run
	// DecisionSink; it must never be represented by approval_instances.
	BusinessTypeWorkflowRunApproval = "run_approval"
	// BusinessTypeRunApproval and BusinessTypeApproval are descriptive aliases
	// retained for callers that use the historical short name.
	BusinessTypeRunApproval            = BusinessTypeWorkflowRunApproval
	BusinessTypeApproval               = BusinessTypeWorkflowRunApproval
	BusinessTypeAppInstallationRequest = "app_installation_request"
	BusinessTypeWikiGenerationRequest  = "kb_wiki_generation_request"
	SubjectTypeServiceAccountCreate    = "service_account_create_request"
	SubjectTypeTeamRoleProposal        = "team_role_proposal"

	RecipientBasisAssignment               = "approval_assignment"
	RecipientBasisApplicant                = "approval_applicant"
	RecipientBasisAppInstallationReviewer  = "app_installation_reviewer"
	RecipientBasisAppInstallationApplicant = "app_installation_applicant"
	RecipientBasisWikiGenerationRequester  = "kb_wiki_generation_requester"
	RecipientBasisWorkflowRunAssignee      = "workflow_run_approval_assignee"
	RecipientBasisAssignee                 = RecipientBasisWorkflowRunAssignee

	ActionApprove = "approve"
	ActionReject  = "reject"

	// ActionSemantics* describe the business intent of an action. The frontend
	// owns the visual treatment (variant, icon, ordering) based on these tags,
	// so the backend never decides UI concerns like color or weight directly.
	ActionSemanticsCommit   = "commit"   // confirms / advances state (e.g. approve)
	ActionSemanticsRevise   = "revise"   // returns for revision (e.g. reject, return)
	ActionSemanticsNavigate = "navigate" // opens an internal or external URL
)

// BuiltinRegistration is intentionally kept in this package-neutral shape so
// the composition root can map it to the app store registry without making
// provisioning depend on the app aggregate.
type BuiltinRegistration struct {
	IdentityID                string
	ServiceDefinitionSlug     string
	ActionHandlerKey          string
	AllowedBusinessNamespaces []string
	AllowedTargetKinds        []string
	AllowedContentKinds       []string
}

func Registration() BuiltinRegistration {
	return BuiltinRegistration{
		IdentityID:                IdentityID,
		ServiceDefinitionSlug:     DefinitionSlug,
		ActionHandlerKey:          HandlerKey,
		AllowedBusinessNamespaces: []string{BusinessNamespace},
		AllowedTargetKinds:        []string{"human_dm", "scope"},
		AllowedContentKinds:       []string{"message", "interactive_card"},
	}
}

func teamRoleProposalClientNotificationID(approvalID string) string {
	return "team-role-proposal:" + strings.TrimSpace(approvalID) + ":review"
}

func agentManagementReviewClientNotificationID(approvalID string) string {
	return "agent-management:" + strings.TrimSpace(approvalID) + ":review"
}

func roleManagementReviewClientNotificationID(approvalID string) string {
	return "role-management:" + strings.TrimSpace(approvalID) + ":review"
}

func appInstallationReviewerClientNotificationID(requestID, memberID string) string {
	return strings.Join([]string{
		"app-installation", strings.TrimSpace(requestID),
		"reviewer", strings.TrimSpace(memberID),
	}, ":")
}

func appInstallationApplicantReceiptClientNotificationID(requestID string) string {
	return "app-installation:" + strings.TrimSpace(requestID) + ":applicant:pending"
}

func appInstallationApplicantResultClientNotificationID(requestID string) string {
	return "app-installation:" + strings.TrimSpace(requestID) + ":applicant:result"
}

func assignmentClientNotificationID(requestID, memberID string) string {
	return strings.Join([]string{
		"service-account-create", strings.TrimSpace(requestID),
		"approver", strings.TrimSpace(memberID),
	}, ":")
}

func applicantReceiptClientNotificationID(requestID string) string {
	return "service-account-create:" + strings.TrimSpace(requestID) + ":applicant:pending"
}

func applicantResultClientNotificationID(requestID string) string {
	return "service-account-create:" + strings.TrimSpace(requestID) + ":applicant:result"
}

func workflowRunApprovalClientNotificationID(runID, effectID string) string {
	return "workflow-run:" + strings.TrimSpace(runID) + ":approval:" + strings.TrimSpace(effectID)
}
