package provider

import (
	"context"

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

type Store interface {
	AuthorizeGitHubAppRegistrationForUser(ctx context.Context, userID, workspaceID string) error
	AuthorizeGitHubAppInstallForUser(ctx context.Context, userID, workspaceID string) error
	GetGitHubAppConfigForUser(ctx context.Context, userID, workspaceID string) (provider.GitHubAppConfigView, error)
	DeleteGitHubAppConfigForUser(ctx context.Context, userID, workspaceID string) (provider.GitHubAppConfigView, error)
	LoadGitHubAppConfigForWorkspace(ctx context.Context, workspaceID string) (provider.GitHubAppConfig, bool, error)
	PrepareGitHubConnectionsForUser(ctx context.Context, userID, workspaceID string, installationIDs []string) (provider.GitHubAppConfig, []string, provider.GitHubConnectionsMutationBase, error)
	ApplyVerifiedGitHubConnectionsForUser(ctx context.Context, userID, workspaceID string, targets []provider.GitHubVerifiedConnectionTarget, base provider.GitHubConnectionsMutationBase) (provider.AppInstallationView, error)
	// Legacy singular administrator helpers remain for callback/test
	// compatibility. New HTTP connection creation uses the active-human batch
	// prepare/apply methods above for both administrators and ordinary members.
	PrepareGitHubConnectionForUser(ctx context.Context, userID, workspaceID, installationID string) (provider.GitHubAppConfig, provider.GitHubConnectionMutationBase, error)
	ApplyGitHubAppSetupForUser(ctx context.Context, userID, workspaceID, installationID, displayLabel string, base provider.GitHubConnectionMutationBase) (provider.AppInstallationView, error)
	ListGitHubConnectionsForUser(ctx context.Context, userID, workspaceID string) ([]provider.AppConnectionView, error)
	PrepareGitHubConnectionDisableForUser(ctx context.Context, userID, workspaceID, connectionID string) (provider.GitHubConnectionMutationBase, error)
	DisableGitHubConnectionForUser(ctx context.Context, userID, workspaceID, connectionID string, base provider.GitHubConnectionMutationBase) error

	GetGiteaAppConfigForUser(ctx context.Context, userID, workspaceID string) (provider.GiteaAppConfigView, error)
	ListGiteaConnectionsForUser(ctx context.Context, userID, workspaceID string) ([]provider.AppConnectionView, error)
}

// GitHubAdminStore owns both GitHub setup admission modes. Administrators
// atomically activate the AgentTeam App and provider config after verification;
// ordinary members may persist only a private verified setup proposal, which
// must later be promoted through the App installation approval flow.
type GitHubAdminStore interface {
	GitHubAppSetupModeForUser(ctx context.Context, userID, workspaceID string) (string, error)
	GitHubConnectionSetupModeForUser(ctx context.Context, userID, workspaceID string) (string, error)
	RequestVerifiedGitHubConnectionForUser(ctx context.Context, userID, workspaceID, externalSubjectRef, displayLabel string, expectedConfig provider.GitHubAppConfig) (app.AppInstallationRequestView, error)
	BeginGitHubAppSetupVerificationForUser(ctx context.Context, userID, workspaceID string, input app.GitHubSetupVerificationInput) (app.GitHubSetupVerificationLease, error)
	ResumeGitHubSetupVerificationForUser(ctx context.Context, userID, workspaceID, mode string) (provider.GitHubAppConfig, app.GitHubSetupVerificationLease, bool, error)
	MarkGitHubSetupVerificationProviderMutationStartedForUser(ctx context.Context, userID, workspaceID, leaseID string) error
	FinalizeGitHubSetupVerificationForRequester(ctx context.Context, userID, workspaceID, leaseID string) (app.GitHubSetupProposalView, error)
	FinalizeGitHubSetupVerificationForWorkspaceAdmin(ctx context.Context, userID, workspaceID, leaseID string) (provider.GitHubAppConfigView, error)
	AbortGitHubSetupVerificationForUser(ctx context.Context, userID, workspaceID, leaseID string) error
	SaveVerifiedGitHubSetupProposalForUser(ctx context.Context, userID, workspaceID string, params provider.UpsertGitHubAppConfigParams) (app.GitHubSetupProposalView, error)
	SaveVerifiedGitHubSetupDraftForRequester(ctx context.Context, userID, workspaceID string, params provider.UpsertGitHubAppConfigParams) (app.GitHubSetupProposalView, error)
	SaveVerifiedGitHubSetupDraftForWorkspaceAdmin(ctx context.Context, userID, workspaceID string, params provider.UpsertGitHubAppConfigParams) (app.GitHubSetupProposalView, error)
	GetGitHubSetupProposalForUser(ctx context.Context, userID, workspaceID string) (app.GitHubSetupProposalView, bool, error)
	GetGitHubSetupDraftForRequester(ctx context.Context, userID, workspaceID, draftID string) (app.GitHubSetupProposalView, provider.GitHubAppConfig, error)
	GetGitHubSetupDraftForWorkspaceAdmin(ctx context.Context, userID, workspaceID, draftID string) (app.GitHubSetupProposalView, provider.GitHubAppConfig, error)
	BeginGitHubSetupCompletionForWorkspaceAdmin(ctx context.Context, userID, workspaceID, draftID string, installationIDs []string) (provider.GitHubAppConfig, app.GitHubSetupCompletionLease, error)
	MarkGitHubSetupCompletionProviderMutationStartedForWorkspaceAdmin(ctx context.Context, userID, workspaceID string, lease app.GitHubSetupCompletionLease, targets []app.GitHubSetupCompletionTarget) error
	FinalizeGitHubSetupCompletionForWorkspaceAdmin(ctx context.Context, userID, workspaceID string, lease app.GitHubSetupCompletionLease) (provider.AppInstallationView, error)
	FinalizeGitHubAppSetupForWorkspaceAdmin(ctx context.Context, userID, workspaceID string, params provider.UpsertGitHubAppConfigParams) (provider.GitHubAppConfigView, error)
}

// GiteaAdminStore owns the privileged direct-mutation path. Keeping it
// separate from Store makes the permission boundary explicit: the read store
// remains workspace-visible, while only these methods may bypass the member
// approval-request path and each method re-authorizes a workspace admin.
type GiteaAdminStore interface {
	SaveGiteaAppConfigForWorkspaceAdmin(ctx context.Context, userID, workspaceID string, params provider.UpsertGiteaAppConfigParams) (provider.GiteaAppConfigView, error)
	CreateGiteaConnectionForWorkspaceAdmin(ctx context.Context, userID, workspaceID, target string) (provider.AppInstallationView, error)
	DisconnectGiteaConnectionForWorkspaceAdmin(ctx context.Context, userID, workspaceID, connectionID string) error
}

type ServiceEventSubscriptionBlocker interface {
	BlockServiceEventSubscriptions(ctx context.Context, workspaceID, provider, connectionRef string) (int, error)
	UnblockServiceEventSubscriptions(ctx context.Context, workspaceID, provider, connectionRef string) (int, error)
}

// AppInstallationRequestProjector is the after-commit delivery surface for
// provider callbacks that materialize the same durable App approval requests
// as the ordinary App HTTP endpoint.
type AppInstallationRequestProjector interface {
	ProjectPendingAppInstallationRequest(context.Context, app.AppInstallationRequestView) ([]app.AppNotificationResult, error)
}

type GitHubConfig struct {
	FlowStateKey []byte
	BaseURL      string
	APIBaseURL   string
}

var (
	ErrNotFound = provider.ErrNotFound
)
