package app

import (
	"time"

	"github.com/tidbcloud/AgentTeam/internal/store/app/registry"
	"github.com/tidbcloud/AgentTeam/internal/store/app/runtime"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
	"github.com/tidbcloud/AgentTeam/internal/store/provider"
)

type AppInstallationView struct {
	ID                string
	AppID             string
	AppSlug           string
	AppName           string
	AvatarURL         string
	InstanceKey       string
	OwnershipKind     string
	OwnerMemberID     string
	MemberID          string
	Handle            string
	InstalledVersion  string
	Connections       []runtime.ConnectionView
	Grants            []string
	RuntimeCapability *registry.AppRuntimeCapabilityView
	CatalogVisibility string
	CanManageApp      bool
	Config            map[string]any
	Enabled           bool
	CreatedAt         time.Time
	UpdatedAt         time.Time
	InChannel         *bool
}

// AppInstallationChannelView is the caller-visible active channel membership
// for one App service member. CanRemove is a presentation hint only; the
// channel membership mutation revalidates the same authority under lock.
type AppInstallationChannelView struct {
	ID          string
	Slug        string
	DisplayName string
	Description string
	Visibility  string
	CanRemove   bool
}

type InstallAppParams struct {
	AppID   string
	AppSlug string
	Config  map[string]any
}

// ConfigureAppInstallationParams is the optimistic-concurrency input for an
// explicit workspace-admin configuration write. ExpectedBaseConfig must match
// the currently installed manifest config before Config is applied.
type ConfigureAppInstallationParams struct {
	ExpectedBaseConfig map[string]any
	Config             map[string]any
}

// GitHubConnectionTargetView is the reviewer-safe projection of one exact,
// server-verified GitHub installation selection. AccountID remains private CAS
// material and is deliberately not exposed through this view.
type GitHubConnectionTargetView struct {
	InstallationID string
	AccountLogin   string
}

type AppInstallationRequestView struct {
	ID             string
	WorkspaceID    string
	AppID          string
	AppSlug        string
	AppName        string
	AppDescription string
	AvatarURL      string
	// CurrentProcessorNames is projection-only presentation data resolved by
	// Approval. It is never persisted or exposed by App API DTOs.
	CurrentProcessorNames []string
	RequestKind           string
	RequestedVersion      string
	BaseConfig            map[string]any
	RequestedConfig       map[string]any
	RequestedScopes       []string
	// AppRuntimeTransports and AppCallbackURL are a safe, immutable review
	// projection captured when an external App installation is requested. They
	// never contain callback signing secrets or runner credentials.
	AppRuntimeTransports []string
	AppCallbackURL       string
	// AppCatalogVisibility is the immutable, reviewer-safe audience requested
	// for a newly created external App. Missing legacy snapshots fail closed to
	// private during approval.
	AppCatalogVisibility string
	// ConnectionTarget is the normalized Gitea owner/repository or organization
	// target proposed by a connect request. It is intentionally projected as a
	// first-class field instead of exposing the internal request snapshot.
	ConnectionTarget string
	// ConnectionTargets is the canonical, numerically sorted GitHub
	// installation set for an initial setup request. Active-App direct connects
	// are deliberately single-target. The singular field remains the first item
	// for legacy consumers.
	ConnectionTargets []string
	// GitHubConnectionTargets carries the safe id/login pairs used by reviewer
	// cards. It never contains provider credentials or the immutable account id.
	GitHubConnectionTargets []GitHubConnectionTargetView
	// ConnectionID and ConnectionLabel identify the exact active Gitea
	// connection snapshotted by a disconnect request.
	ConnectionID    string
	ConnectionLabel string
	Status          string
	// ApprovalRequired is the durable trust-boundary marker separating true
	// human-review requests from internal GitHub setup/recovery leases stored in
	// the same table. Approval surfaces and decision methods fail closed on it.
	ApprovalRequired bool
	// ReviewState is an internal durable projection fence. It is not exposed by
	// browser DTOs; Approval uses it to ensure every current and future
	// reviewer sees the same safe action set for a stale pending proposal.
	ReviewState            string
	RequestReason          string
	RequestedByMemberID    string
	RequestedByUserID      string
	RequestedByDisplayName string
	DecidedByMemberID      string
	DecisionReason         string
	InstallationID         string
	CreatedAt              time.Time
	UpdatedAt              time.Time
	DecidedAt              *time.Time
	// Gitea provider proposals keep encrypted credential envelopes only in these
	// internal snapshots. Exported config maps are always browser/card-safe.
	storedBaseConfig      map[string]any
	storedRequestedConfig map[string]any
}

type RequestAppInstallationParams struct {
	AppID              string
	AppSlug            string
	InstallationID     string
	RequestKind        string
	ConnectionTarget   string
	ConnectionTargets  []string
	ConnectionID       string
	ExpectedBaseConfig map[string]any
	Config             map[string]any
	Reason             string
	// GitHubSetupProposalID is the opaque, requester-bound id returned only
	// after GitHub registration or recovery has been verified. GitHub install
	// requests must consume this draft instead of accepting provider credentials
	// in the public request JSON.
	GitHubSetupProposalID string
}

// GitHubSetupProposalView is the browser-safe projection of one verified,
// owner-bound GitHub setup draft. Provider credentials and their encrypted
// storage envelopes are deliberately absent. Requester and administrator
// drafts use separate store methods and strict mode filters.
type GitHubSetupProposalView struct {
	ID         string
	Ready      bool
	AppID      string
	AppSlug    string
	AppName    string
	OwnerLogin string
	ExpiresAt  time.Time
}

// GitHubSetupVerificationInput starts a short-lived server-side lease before
// recovery mutates the GitHub App webhook. ExpectedConfig* pins the active
// provider configuration observed by the caller; an empty id means that no
// active configuration was observed.
type GitHubSetupVerificationInput struct {
	Mode                    string
	Config                  provider.UpsertGitHubAppConfigParams
	ExpectedConfigID        string
	ExpectedConfigUpdatedAt time.Time
	// RequireActiveInstallation makes the legacy PUT /config path an update or
	// config-missing repair only. Begin checks this under the canonical mutation
	// lock so a stale HTTP preflight cannot activate a truly fresh workspace.
	RequireActiveInstallation bool
}

// GitHubSetupVerificationLease is internal-only. Its id and webhook secret
// must never be returned to a browser; the API uses them only across the
// external webhook PATCH and the local CAS finalize.
type GitHubSetupVerificationLease struct {
	ID            string
	Mode          string
	WebhookSecret string
}

// GitHubSetupCompletionLease is an internal-only, short-lived operation
// created after an administrator selects the complete desired installation set
// for a fresh workspace setup. The browser knows only the setup draft id; this
// lease binds that draft to one canonical set (one to fifty installations)
// while the API re-verifies every installation, patches the provider webhook,
// and atomically materializes the local App/config/connections state.
type GitHubSetupCompletionLease struct {
	ID              string
	DraftID         string
	InstallationID  string
	InstallationIDs []string
}

// GitHubSetupCompletionTarget is server-derived from an exact GitHub GET for
// one administrator setup target. AccountID is internal CAS material: it is
// persisted only in the short-lived encrypted-operation row and never exposed
// by browser DTOs.
type GitHubSetupCompletionTarget struct {
	InstallationID string
	AccountLogin   string
	AccountID      int64
}

// AppInstallationReviewSnapshot is the allowlisted, non-secret subset of an
// external App manifest that workspace reviewers must see before approval.
type AppInstallationReviewSnapshot struct {
	RuntimeTransports []string
	CallbackURL       string
	CatalogVisibility string
}

// AppVisibilityUpdateResult is the durable outcome of one workspace App
// audience mutation. RemovedChannelIDs identifies every channel membership
// removed in the same transaction when the target audience is private.
type AppVisibilityUpdateResult struct {
	CatalogVisibility string
	RemovedChannelIDs []string
}

type DecideAppInstallationRequestParams struct {
	Reason string
}

type AppWebhookDeliveryView struct {
	ID                   string
	InstallationID       string
	AppID                string
	AppSlug              string
	AppName              string
	DeliveryKey          string
	EventType            string
	PayloadExcerpt       string
	MatchedSubscriptions []MatchedWebhookSubscription
	Outcome              string
	ProcessedAt          *time.Time
	ErrorMessage         string
	CreatedAt            time.Time
	UpdatedAt            time.Time
}

type MatchedWebhookSubscription struct {
	ID                 string
	ThreadID           string
	ResourceIdentifier string
}

type AppWebhookResult struct {
	Duplicate                bool
	MatchedSubscriptionCount int
	WorkspaceID              string
	Deliveries               []message.MessageDelivery
}
