package dto

import (
	"encoding/json"
	"time"
)

// AppRunnerCredentialResponse is the browser-facing runner credential metadata shape.
type AppRunnerCredentialResponse struct {
	ID                    string         `json:"id"`
	WorkspaceID           string         `json:"workspaceId"`
	ServiceDefinitionID   string         `json:"serviceDefinitionId"`
	ServiceInstallationID string         `json:"serviceInstallationId"`
	ServiceMemberID       string         `json:"serviceMemberId"`
	CredentialKind        string         `json:"credentialKind"`
	TransportKind         string         `json:"transportKind"`
	Name                  string         `json:"name"`
	TokenHint             string         `json:"tokenHint"`
	Status                string         `json:"status"`
	CreatedByMemberID     string         `json:"createdByMemberId"`
	Metadata              map[string]any `json:"metadata"`
	CreatedAt             time.Time      `json:"createdAt"`
	UpdatedAt             time.Time      `json:"updatedAt"`
	LastUsedAt            *time.Time     `json:"lastUsedAt,omitempty"`
	DisabledAt            *time.Time     `json:"disabledAt,omitempty"`
	ExpiresAt             *time.Time     `json:"expiresAt,omitempty"`
}

// AppRunnerCredentialTokenResponse returns a runner credential and the plaintext token once.
type AppRunnerCredentialTokenResponse struct {
	Credential AppRunnerCredentialResponse `json:"credential"`
	Token      string                      `json:"token"`
}

// AppCallbackSecretResponse is returned only by explicit callback-secret
// creation/rotation and reveals the new plaintext exactly once.
type AppCallbackSecretResponse struct {
	AppID                 string `json:"appId"`
	AppSlug               string `json:"appSlug"`
	CallbackSigningSecret string `json:"callbackSigningSecret"`
}

// AppInitialCredentialsStatusResponse is the secret-free installed App setup
// state. It intentionally does not identify the installation requester.
type AppInitialCredentialsStatusResponse struct {
	Status string `json:"status"`
}

// AppInitialCredentialsClaimResponse returns the initial runtime credential
// set exactly once. Fields are transport-dependent.
type AppInitialCredentialsClaimResponse struct {
	CallbackSigningSecret string `json:"callbackSigningSecret,omitempty"`
	RunnerToken           string `json:"runnerToken,omitempty"`
}

// AppRunnerSessionResponse is the runtime-facing runner session shape.
type AppRunnerSessionResponse struct {
	ID                         string         `json:"id"`
	WorkspaceID                string         `json:"workspaceId"`
	ServiceDefinitionID        string         `json:"serviceDefinitionId"`
	ServiceInstallationID      string         `json:"serviceInstallationId"`
	ServiceMemberID            string         `json:"serviceMemberId"`
	ServiceRuntimeCredentialID string         `json:"serviceRuntimeCredentialId"`
	RunnerID                   string         `json:"runnerId"`
	RunnerVersion              string         `json:"runnerVersion"`
	Status                     string         `json:"status"`
	Capabilities               map[string]any `json:"capabilities"`
	Metadata                   map[string]any `json:"metadata"`
	LastHeartbeatAt            *time.Time     `json:"lastHeartbeatAt,omitempty"`
	LastClaimAt                *time.Time     `json:"lastClaimAt,omitempty"`
	CreatedAt                  time.Time      `json:"createdAt"`
	UpdatedAt                  time.Time      `json:"updatedAt"`
}

// AppRunnerDeliveryEnvelopeResponse is one claimed runner delivery envelope.
type AppRunnerDeliveryEnvelopeResponse struct {
	EnvelopeID    string          `json:"envelopeId"`
	DeliveryID    string          `json:"deliveryId"`
	AttemptID     string          `json:"attemptId"`
	EventType     string          `json:"eventType"`
	EventAction   string          `json:"eventAction,omitempty"`
	Payload       json.RawMessage `json:"payload"`
	DeliveryToken string          `json:"deliveryToken"`
	IssuedAt      time.Time       `json:"issuedAt"`
}

// AppRunnerClaimResponse returns one runner session and its claimed envelopes.
type AppRunnerClaimResponse struct {
	Session   AppRunnerSessionResponse            `json:"session"`
	Envelopes []AppRunnerDeliveryEnvelopeResponse `json:"envelopes"`
}

// AppRunnerStreamEventResponse is one NDJSON event emitted by the runner stream.
type AppRunnerStreamEventResponse struct {
	Type     string                             `json:"type"`
	Session  *AppRunnerSessionResponse          `json:"session,omitempty"`
	Envelope *AppRunnerDeliveryEnvelopeResponse `json:"envelope,omitempty"`
	Error    *AppRunnerStreamErrorResponse      `json:"error,omitempty"`
}

// AppRunnerStreamErrorResponse describes a terminal runner stream error event.
type AppRunnerStreamErrorResponse struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

// AppRuntimeReplyResponse is the runtime-facing reply result.
type AppRuntimeReplyResponse struct {
	DeliveryID     string `json:"deliveryId"`
	AttemptID      string `json:"attemptId"`
	DeliveryStatus string `json:"deliveryStatus"`
	AttemptStatus  string `json:"attemptStatus"`
	EffectID       string `json:"effectId"`
	EffectKind     string `json:"effectKind"`
	EffectRef      string `json:"effectRef"`
	MessageID      string `json:"messageId,omitempty"`
}

// AppRuntimeDeliveryActionResponse is the runtime-facing ack/fail result.
type AppRuntimeDeliveryActionResponse struct {
	DeliveryID     string `json:"deliveryId"`
	AttemptID      string `json:"attemptId"`
	DeliveryStatus string `json:"deliveryStatus"`
	AttemptStatus  string `json:"attemptStatus"`
	ErrorCode      string `json:"errorCode,omitempty"`
	ErrorDetail    string `json:"errorDetail,omitempty"`
}

// AppRunnerCredentialCreateRequest is the request body for creating a App runner stream token.
type AppRunnerCredentialCreateRequest struct {
	Name      string         `json:"name"`
	ExpiresAt *time.Time     `json:"expiresAt"`
	Metadata  map[string]any `json:"metadata"`
}

// AppRunnerHeartbeatRequest records one runner stream heartbeat.
type AppRunnerHeartbeatRequest struct {
	RunnerID      string         `json:"runnerId"`
	RunnerVersion string         `json:"runnerVersion"`
	Capabilities  map[string]any `json:"capabilities"`
	Metadata      map[string]any `json:"metadata"`
}

// AppRunnerClaimRequest records one runner stream delivery claim.
type AppRunnerClaimRequest struct {
	RunnerID      string         `json:"runnerId"`
	RunnerVersion string         `json:"runnerVersion"`
	Capabilities  map[string]any `json:"capabilities"`
	Metadata      map[string]any `json:"metadata"`
	Limit         int            `json:"limit"`
	LeaseSeconds  int            `json:"leaseSeconds"`
}

// AppRuntimeReplyRequest writes one App reply for a leased delivery attempt.
type AppRuntimeReplyRequest struct {
	AttemptID      string         `json:"attemptId"`
	Content        string         `json:"content"`
	Metadata       map[string]any `json:"metadata"`
	IdempotencyKey string         `json:"idempotencyKey"`
}

// AppRuntimeAckRequest marks one App delivery attempt complete.
type AppRuntimeAckRequest struct {
	AttemptID string         `json:"attemptId"`
	Result    map[string]any `json:"result"`
}

// AppRuntimeFailRequest marks one App delivery attempt failed.
type AppRuntimeFailRequest struct {
	AttemptID string         `json:"attemptId"`
	Code      string         `json:"code"`
	Message   string         `json:"message"`
	Result    map[string]any `json:"result"`
}
