package dto

import "github.com/tidbcloud/AgentTeam/internal/service/memory"

type Memory struct {
	ID                string             `json:"id"`
	Name              string             `json:"name"`
	Description       string             `json:"description,omitempty"`
	Slug              string             `json:"slug,omitempty"`
	StorageScope      string             `json:"storageScope"`
	StorageOwnerLogin string             `json:"storageOwnerLogin"`
	Repositories      MemoryRepositories `json:"repositories"`
	CreatedAt         string             `json:"createdAt"`
	UpdatedAt         string             `json:"updatedAt"`
	IsActive          bool               `json:"isActive"`
	Pinned            bool               `json:"pinned"`
	PinnedAt          string             `json:"pinnedAt,omitempty"`
	Role              string             `json:"role,omitempty"`
	CanManage         bool               `json:"canManage"`
	CreatedBy         string             `json:"createdBy,omitempty"`
	UpdatedBy         string             `json:"updatedBy,omitempty"`
}

type MemoryRepositories struct {
	Primary *ResourceRepositoryRef `json:"canonical,omitempty"`
}

type MemoryListResponse struct {
	Items   []Memory `json:"items"`
	Page    int      `json:"page"`
	PerPage int      `json:"perPage"`
	Total   int64    `json:"total"`
	HasMore bool     `json:"hasMore"`
}

type AgentAccessibleMemory struct {
	ID                          string                 `json:"id"`
	Name                        string                 `json:"name"`
	Description                 string                 `json:"description,omitempty"`
	AccessLevel                 string                 `json:"accessLevel"`
	PermissionSetAt             string                 `json:"permissionSetAt"`
	UpdatedAt                   string                 `json:"updatedAt"`
	Repository                  *ResourceRepositoryRef `json:"repository,omitempty"`
	Branch                      string                 `json:"branch"`
	ImportExistingLocalContent  bool                   `json:"importExistingLocalContent,omitempty"`
	ReplaceLocalContentOnSwitch bool                   `json:"replaceLocalContentOnSwitch,omitempty"`
	SyncProtocol                string                 `json:"syncProtocol"`
	ContentID                   string                 `json:"contentId,omitempty"`
	ContentVersionID            string                 `json:"contentVersionId,omitempty"`
	ContentGeneration           uint64                 `json:"contentGeneration,omitempty"`
	AcknowledgedSequence        uint64                 `json:"acknowledgedSequence,omitempty"`
	ActiveReplicaID             string                 `json:"activeReplicaId,omitempty"`
}

type AgentCloudMemory struct {
	AgentID                    string                 `json:"agentId"`
	Enabled                    bool                   `json:"enabled"`
	MemoryID                   string                 `json:"memoryId,omitempty"`
	Name                       string                 `json:"name,omitempty"`
	Branch                     string                 `json:"branch,omitempty"`
	Repository                 *ResourceRepositoryRef `json:"repository,omitempty"`
	Status                     string                 `json:"status"`
	SyncStatus                 string                 `json:"syncStatus"`
	LastSyncAt                 string                 `json:"lastSyncAt,omitempty"`
	LastBackupAt               string                 `json:"lastBackupAt,omitempty"`
	ImportExistingLocalContent bool                   `json:"importExistingLocalContent,omitempty"`
}

type AgentCloudMemoryEnableRequest struct {
	ImportExistingLocalContent *bool  `json:"importExistingLocalContent,omitempty"`
	TemplateLocale             string `json:"templateLocale,omitempty"`
}

func (r AgentCloudMemoryEnableRequest) Input() memory.AgentCloudMemoryEnableMutation {
	return memory.AgentCloudMemoryEnableMutation{
		ImportExistingLocalContent: r.ImportExistingLocalContent,
		TemplateLocale:             r.TemplateLocale,
	}
}

type AgentCloudMemoryBackup struct {
	TagName   string `json:"tagName"`
	Name      string `json:"name"`
	CommitSHA string `json:"commitSha,omitempty"`
	CreatedAt string `json:"createdAt,omitempty"`
}

type AgentCloudMemoryBackupListResponse struct {
	Items   []AgentCloudMemoryBackup `json:"items"`
	Page    int                      `json:"page"`
	PerPage int                      `json:"perPage"`
	HasMore bool                     `json:"hasMore"`
}

type AgentCloudMemoryBackupCreateRequest struct {
	Name string `json:"name,omitempty"`
}

func (r AgentCloudMemoryBackupCreateRequest) Input() memory.AgentCloudMemoryBackupCreateMutation {
	return memory.AgentCloudMemoryBackupCreateMutation{Name: r.Name}
}

type AgentCloudMemoryBackupRestoreRequest struct {
	TagName string `json:"tagName"`
}

// AgentAccessBatchRequest is the body of POST /memory/agents/access:batch.
// Desktop clients send the list of server-known agent IDs they currently host,
// and MeshX returns each agent's bound memory with enough metadata to locally
// clone the backing repo.
type AgentAccessBatchRequest struct {
	AgentIDs []string `json:"agentIds"`
}

// AgentAccessBatchResponse maps each requested agent ID to its accessible
// memory binding and the server-selected sync protocol. Agents that have no
// binding map to null so callers can distinguish "no access" from "agent
// dropped from response".
//
// SyncToken carries a short-lived AGS-issued token scoped only to legacy Git
// repositories referenced in this response. Native-only responses omit it.
type AgentAccessBatchResponse struct {
	Agents           map[string]*AgentAccessibleMemory `json:"agents"`
	SyncToken        string                            `json:"syncToken,omitempty"`
	SyncTokenExpires string                            `json:"syncTokenExpires,omitempty"`
}

type AgentAssetAccessEventLeaseRequest struct {
	LeaseOwner   string   `json:"lease_owner"`
	LeaseSeconds int64    `json:"lease_seconds,omitempty"`
	Limit        int      `json:"limit,omitempty"`
	WorkspaceIDs []string `json:"workspace_ids,omitempty"`
}

type AgentAssetAccessEventFailedRequest struct {
	LeaseOwner    string `json:"lease_owner"`
	LastError     string `json:"last_error,omitempty"`
	NextAttemptAt string `json:"next_attempt_at,omitempty"`
}

type AgentAssetAccessEventDeliveredRequest struct {
	LeaseOwner string `json:"lease_owner"`
}

type AgentAssetAccessEvent struct {
	EventID     string   `json:"event_id"`
	WorkspaceID string   `json:"workspace_id"`
	AgentIDs    []string `json:"agent_ids"`
	AssetTypes  []string `json:"asset_types"`
	Version     int64    `json:"version"`
	OccurredAt  string   `json:"occurred_at"`
	Source      string   `json:"source"`
	Attempts    int      `json:"attempts,omitempty"`
	MaxAttempts int      `json:"max_attempts,omitempty"`
}

type AgentAssetAccessEventLeaseResponse struct {
	Events []AgentAssetAccessEvent `json:"events"`
}

type AgentAssetAccessEventAckResponse struct {
	Updated bool `json:"updated"`
	Failed  bool `json:"failed,omitempty"`
}

type AgentOwnership struct {
	ID          string `json:"id"`
	Name        string `json:"name,omitempty"`
	DisplayName string `json:"displayName,omitempty"`
}

type AgentMemoryBindingSummary struct {
	ID                          string `json:"id"`
	AgentID                     string `json:"agentId"`
	MemoryID                    string `json:"memoryId"`
	Branch                      string `json:"branch"`
	ImportExistingLocalContent  bool   `json:"importExistingLocalContent,omitempty"`
	ReplaceLocalContentOnSwitch bool   `json:"replaceLocalContentOnSwitch,omitempty"`
	CreatedBy                   string `json:"createdBy"`
	UpdatedBy                   string `json:"updatedBy"`
	CreatedAt                   string `json:"createdAt"`
	UpdatedAt                   string `json:"updatedAt"`
}

type AgentMemoryBindingMemory struct {
	ID                          string                 `json:"id"`
	Slug                        string                 `json:"slug,omitempty"`
	Name                        string                 `json:"name"`
	Description                 string                 `json:"description,omitempty"`
	IsActive                    bool                   `json:"isActive"`
	Role                        string                 `json:"role,omitempty"`
	CanManage                   bool                   `json:"canManage"`
	CanBind                     bool                   `json:"canBind"`
	Repository                  *ResourceRepositoryRef `json:"repository,omitempty"`
	BoundAgentID                string                 `json:"boundAgentId,omitempty"`
	BoundAgentName              string                 `json:"boundAgentName,omitempty"`
	BoundBranch                 string                 `json:"boundBranch,omitempty"`
	ImportExistingLocalContent  bool                   `json:"importExistingLocalContent,omitempty"`
	ReplaceLocalContentOnSwitch bool                   `json:"replaceLocalContentOnSwitch,omitempty"`
	UpdatedAt                   string                 `json:"updatedAt"`
}

type AgentMemoryBindingsResponse struct {
	OwnedAgents []AgentOwnership            `json:"ownedAgents"`
	Bindings    []AgentMemoryBindingSummary `json:"bindings"`
	Memories    []AgentMemoryBindingMemory  `json:"memories"`
}

type MemoryPermissionGrant struct {
	ID          string `json:"id"`
	MemoryID    string `json:"memoryId"`
	SubjectType string `json:"subjectType"`
	SubjectID   string `json:"subjectId"`
	Role        string `json:"role"`
	CreatedBy   string `json:"createdBy"`
	UpdatedBy   string `json:"updatedBy"`
	CreatedAt   string `json:"createdAt"`
	UpdatedAt   string `json:"updatedAt"`
}

type MemoryPermissionsResponse struct {
	MyRole    string                  `json:"myRole"`
	CanManage bool                    `json:"canManage"`
	Owner     *MemoryPermissionGrant  `json:"owner,omitempty"`
	Members   []MemoryPermissionGrant `json:"members"`
}

type MemoryPermissionGrantRequest struct {
	SubjectType string `json:"subjectType"`
	SubjectID   string `json:"subjectId"`
	Role        string `json:"role"`
}

func (r MemoryPermissionGrantRequest) Input() memory.MemoryPermissionGrantMutation {
	return memory.MemoryPermissionGrantMutation{SubjectType: r.SubjectType, SubjectID: r.SubjectID, Role: r.Role}
}

type AgentMemoryBindingRequest struct {
	MemoryID                    string `json:"memoryId"`
	Branch                      string `json:"branch"`
	ImportExistingLocalContent  bool   `json:"importExistingLocalContent,omitempty"`
	ReplaceLocalContentOnSwitch bool   `json:"replaceLocalContentOnSwitch,omitempty"`
}

func (r AgentMemoryBindingRequest) Input() memory.AgentMemoryBindingMutation {
	return memory.AgentMemoryBindingMutation{MemoryID: r.MemoryID, Branch: r.Branch, ImportExistingLocalContent: r.ImportExistingLocalContent, ReplaceLocalContentOnSwitch: r.ReplaceLocalContentOnSwitch}
}

type AgentMemoryBindingResponse struct {
	AgentID                     string `json:"agentId"`
	MemoryID                    string `json:"memoryId,omitempty"`
	PreviousMemoryID            string `json:"previousMemoryId,omitempty"`
	Branch                      string `json:"branch,omitempty"`
	ImportExistingLocalContent  bool   `json:"importExistingLocalContent,omitempty"`
	ReplaceLocalContentOnSwitch bool   `json:"replaceLocalContentOnSwitch,omitempty"`
	Unbound                     bool   `json:"unbound,omitempty"`
}

type MemoryCreateRequest struct {
	Name             string `json:"name"`
	RepoNameOverride string `json:"repoNameOverride,omitempty"`
	Description      string `json:"description"`
	StorageScope     string `json:"storageScope,omitempty"`
	IsActive         *bool  `json:"isActive"`
	TemplateLocale   string `json:"templateLocale,omitempty"`
}

func (r MemoryCreateRequest) Input() memory.MemoryCreateMutation {
	return memory.MemoryCreateMutation{Name: r.Name, RepoNameOverride: r.RepoNameOverride, Description: r.Description, StorageScope: r.StorageScope, IsActive: r.IsActive, TemplateLocale: r.TemplateLocale}
}

type MemoryUpdateRequest struct {
	Name        string `json:"name"`
	Slug        string `json:"slug"`
	Description string `json:"description"`
	IsActive    *bool  `json:"isActive"`
}

func (r MemoryUpdateRequest) Input() memory.MemoryUpdateMutation {
	return memory.MemoryUpdateMutation{Name: r.Name, Slug: r.Slug, Description: r.Description, IsActive: r.IsActive}
}

type MemoryForkRequest struct {
	Name             string `json:"name"`
	RepoNameOverride string `json:"repoNameOverride,omitempty"`
	Description      string `json:"description"`
	StorageScope     string `json:"storageScope,omitempty"`
}

// MemoryContentFileInput is one regular file in a complete Memory checkpoint
// tree. contentBase64 keeps the wire format binary-safe without exposing a
// repository or filesystem path.
type MemoryContentFileInput struct {
	Path          string `json:"path"`
	ContentBase64 string `json:"contentBase64"`
	Executable    bool   `json:"executable,omitempty"`
}

type MemoryCheckpointPublishRequest struct {
	OperationID            string                   `json:"operationId"`
	ReplicaID              string                   `json:"replicaId"`
	ExpectedVersionID      string                   `json:"expectedVersionId"`
	Generation             uint64                   `json:"generation"`
	CoveredFromSequence    uint64                   `json:"coveredFromSequence"`
	CoveredThroughSequence uint64                   `json:"coveredThroughSequence"`
	Files                  []MemoryContentFileInput `json:"files"`
}

type MemoryContentVersion struct {
	VersionID              string `json:"versionId"`
	ParentVersionID        string `json:"parentVersionId,omitempty"`
	TargetVersionID        string `json:"targetVersionId,omitempty"`
	OperationID            string `json:"operationId"`
	OperationKind          string `json:"operationKind"`
	ReplicaID              string `json:"replicaId,omitempty"`
	CoveredFromSequence    uint64 `json:"coveredFromSequence,omitempty"`
	CoveredThroughSequence uint64 `json:"coveredThroughSequence,omitempty"`
	Generation             uint64 `json:"generation"`
	RootDigest             string `json:"rootDigest"`
	FileCount              int    `json:"fileCount"`
	SizeBytes              int64  `json:"sizeBytes"`
	SourceAuthorName       string `json:"sourceAuthorName,omitempty"`
	SourceAuthorEmail      string `json:"sourceAuthorEmail,omitempty"`
	SourceMessage          string `json:"sourceMessage,omitempty"`
	CreatedBy              string `json:"createdBy"`
	CreatedAt              string `json:"createdAt"`
}

type MemoryContentVersionListResponse struct {
	Items   []MemoryContentVersion `json:"items"`
	Page    int                    `json:"page"`
	PerPage int                    `json:"perPage"`
	HasMore bool                   `json:"hasMore"`
}

type MemoryContentCompareEntry struct {
	Path         string `json:"path"`
	Change       string `json:"change"`
	BeforeDigest string `json:"beforeDigest,omitempty"`
	AfterDigest  string `json:"afterDigest,omitempty"`
}

type MemoryContentCompareResponse struct {
	Items []MemoryContentCompareEntry `json:"items"`
}

type MemoryContentBackupCreateRequest struct {
	ExpectedVersionID string `json:"expectedVersionId"`
	Generation        uint64 `json:"generation"`
	Label             string `json:"label"`
}

type MemoryContentBackup struct {
	ID        string `json:"id"`
	VersionID string `json:"versionId"`
	Label     string `json:"label"`
	CreatedBy string `json:"createdBy"`
	CreatedAt string `json:"createdAt"`
}

type MemoryContentBackupListResponse struct {
	Items []MemoryContentBackup `json:"items"`
}

type MemoryContentRestoreRequest struct {
	OperationID       string `json:"operationId"`
	ExpectedVersionID string `json:"expectedVersionId"`
	TargetVersionID   string `json:"targetVersionId"`
	Generation        uint64 `json:"generation"`
}

func (r MemoryForkRequest) Input() memory.MemoryForkMutation {
	return memory.MemoryForkMutation{Name: r.Name, RepoNameOverride: r.RepoNameOverride, Description: r.Description, StorageScope: r.StorageScope}
}
