package dto

import "time"

// WorkspaceAppInstallationCreateRequest is the App install body for POST
// /api/v1/workspaces/:workspaceId/app-installations. Ownership selects the
// installation mode: "workspace" (default, administrator path) or
// "personal" (member self-service, owner-managed).
type WorkspaceAppInstallationCreateRequest struct {
	AppID     string         `json:"appId"`
	AppSlug   string         `json:"appSlug"`
	Config    map[string]any `json:"config"`
	Ownership string         `json:"ownership"`
}

// InstallationAccessGrantCreateRequest grants use or manage access on one
// App installation to a human member or an agent.
type InstallationAccessGrantCreateRequest struct {
	PrincipalKind string   `json:"principalKind" binding:"required"`
	PrincipalRef  string   `json:"principalRef" binding:"required"`
	AccessRole    string   `json:"accessRole"`
	Scopes        []string `json:"scopes"`
}

// WorkspaceAppInstallationConfigureRequest is the direct manifest config body
// for PATCH /api/v1/workspaces/:workspaceId/app-installations/:id. Authorization
// is resolved from the current installation and viewer on the server.
type WorkspaceAppInstallationConfigureRequest struct {
	ExpectedBaseConfig map[string]any `json:"expectedBaseConfig"`
	Config             map[string]any `json:"config"`
}

// WorkspaceInstallationExtensionCreateRequest selects one App-advertised
// Extension Definition under a Workspace App Installation.
type WorkspaceInstallationExtensionCreateRequest struct {
	DefinitionDomain string `json:"definitionDomain" binding:"required"`
	ExtensionName    string `json:"extensionName"`
}

// WorkspaceInstallationExtensionUpdateRequest applies exactly one selection
// mutation. Pointers preserve the distinction between omitted and false.
type WorkspaceInstallationExtensionUpdateRequest struct {
	ExtensionName *string `json:"extensionName"`
	Enabled       *bool   `json:"enabled"`
}

// SearchEngineConnectionPutRequest contains provider-owned non-secret config
// and write-only credentials.
type SearchEngineConnectionPutRequest struct {
	Config      map[string]any `json:"config"`
	Credentials map[string]any `json:"credentials"`
}

// WorkspaceAppInstallationRequestCreateRequest is the request body for
// POST /api/v1/workspaces/:workspaceId/app-installation-requests.
type WorkspaceAppInstallationRequestCreateRequest struct {
	AppID                 string         `json:"appId"`
	AppSlug               string         `json:"appSlug"`
	InstallationID        string         `json:"installationId"`
	RequestKind           string         `json:"requestKind"`
	ConnectionTarget      string         `json:"connectionTarget"`
	ConnectionTargets     []string       `json:"connectionTargets"`
	ConnectionID          string         `json:"connectionId"`
	ExpectedBaseConfig    map[string]any `json:"expectedBaseConfig"`
	Config                map[string]any `json:"config"`
	GitHubSetupProposalID string         `json:"githubSetupProposalId"`
	Reason                string         `json:"reason"`
}

// WorkspaceCustomAppRequestCreateRequest registers one external App
// manifest and submits its initial workspace installation for approval.
type WorkspaceCustomAppRequestCreateRequest struct {
	Slug              string         `json:"slug"`
	Name              string         `json:"name"`
	Description       string         `json:"description"`
	AvatarURL         string         `json:"avatarUrl"`
	Manifest          map[string]any `json:"manifest"`
	Config            map[string]any `json:"config"`
	Reason            string         `json:"reason"`
	CatalogVisibility string         `json:"catalogVisibility"`
}

// WorkspaceAppDisplayNameUpdateRequest is the request body for updating the
// display name of one active external App installation.
type WorkspaceAppDisplayNameUpdateRequest struct {
	Name string `json:"name"`
}

// WorkspaceAppVisibilityUpdateRequest changes the workspace-local catalog
// audience of one active external App.
type WorkspaceAppVisibilityUpdateRequest struct {
	CatalogVisibility string `json:"catalogVisibility"`
}

// WorkspaceAppPermissionsUpdateRequest narrows one active external App's
// effective permission scopes to a subset of its pinned manifest capability
// scopes. ExpectedPolicyDigest is the optimistic-concurrency token from the
// last GET.
type WorkspaceAppPermissionsUpdateRequest struct {
	Scopes               []string `json:"scopes"`
	ExpectedPolicyDigest string   `json:"expectedPolicyDigest"`
}

// WorkspaceCustomAppCreateRequest registers and installs one external
// App directly for a workspace owner/admin. It deliberately has no approval
// reason because no approval request is created.
type WorkspaceCustomAppCreateRequest struct {
	Slug              string         `json:"slug"`
	Name              string         `json:"name"`
	Description       string         `json:"description"`
	AvatarURL         string         `json:"avatarUrl"`
	Manifest          map[string]any `json:"manifest"`
	Config            map[string]any `json:"config"`
	CatalogVisibility string         `json:"catalogVisibility"`
}

// WorkspaceAppManagerAddRequest grants full App management authority to one
// active Human member of the workspace.
type WorkspaceAppManagerAddRequest struct {
	MemberID string `json:"memberId" binding:"required"`
}

// WorkspaceAppAvatarUpdateRequest applies one immutable app-owned avatar
// asset. An empty id clears the App avatar.
type WorkspaceAppAvatarUpdateRequest struct {
	AvatarAssetID string `json:"avatarAssetId"`
}

// WorkspaceAppInstallationRequestDecisionRequest is the request body for
// POST /api/v1/workspaces/:workspaceId/app-installation-requests/:requestId:approve and :reject.
type WorkspaceAppInstallationRequestDecisionRequest struct {
	Reason string `json:"reason"`
}

// AgentAppAuthorizationRequest is the request body for enabling an app MCP for
// one agent from the agent settings UI.
type AgentAppAuthorizationRequest struct {
	AppInstallationID string `json:"appInstallationId"`
}

// ServiceEventSubscriptionCreateRequest is the canonical request body for creating an app service-event subscription.
type ServiceEventSubscriptionCreateRequest struct {
	Target          string   `json:"target"`
	PRRefOrURL      string   `json:"prRefOrUrl"`
	Events          []string `json:"events"`
	NotifyPrincipal *bool    `json:"notifyPrincipal"`
}

// ProviderWatchCreateRequest is the legacy browser compatibility request body
// for provider-watch routes.
type ProviderWatchCreateRequest = ServiceEventSubscriptionCreateRequest

// ExtensionProviderConnectionPutRequest carries the provider connection
// credential object for the extension connection flow. ExpectedUpdatedAt is
// the connection version the caller last saw: a concurrent update advances
// it and the write is rejected with a conflict instead of silently merging
// stale "keep stored" secrets back over rotated values.
type ExtensionProviderConnectionPutRequest struct {
	Credentials       map[string]string `json:"credentials"`
	ExpectedUpdatedAt *time.Time        `json:"expectedUpdatedAt,omitempty"`
}
