package domain

import (
	"time"
)

// WebhookID is a strongly-typed identifier for webhooks.
type WebhookID string

// String returns the webhook ID as a string.
func (id WebhookID) String() string {
	return string(id)
}

// WebhookEventType represents the type of event that triggers a webhook.
type WebhookEventType string

// Available webhook event types.
const (
	WebhookEventCommandStarted   WebhookEventType = "command.started"
	WebhookEventCommandCompleted WebhookEventType = "command.completed"
	WebhookEventCommandFailed    WebhookEventType = "command.failed"
	WebhookEventPodReady         WebhookEventType = "pod.ready"
	WebhookEventPodFailed        WebhookEventType = "pod.failed"

	// Saga events
	WebhookEventSagaStarted       WebhookEventType = "saga.started"
	WebhookEventSagaStepStarted   WebhookEventType = "saga.step.started"
	WebhookEventSagaStepCompleted WebhookEventType = "saga.step.completed"
	WebhookEventSagaStepFailed    WebhookEventType = "saga.step.failed"
	WebhookEventSagaStepRetrying  WebhookEventType = "saga.step.retrying"
	WebhookEventSagaCompleted     WebhookEventType = "saga.completed"
	WebhookEventSagaFailed        WebhookEventType = "saga.failed"
	WebhookEventSagaCompensating  WebhookEventType = "saga.compensating"
	WebhookEventSagaCompensated   WebhookEventType = "saga.compensated"
)

// AllWebhookEventTypes lists all valid webhook event types.
var AllWebhookEventTypes = []WebhookEventType{
	WebhookEventCommandStarted,
	WebhookEventCommandCompleted,
	WebhookEventCommandFailed,
	WebhookEventPodReady,
	WebhookEventPodFailed,
	WebhookEventSagaStarted,
	WebhookEventSagaStepStarted,
	WebhookEventSagaStepCompleted,
	WebhookEventSagaStepFailed,
	WebhookEventSagaStepRetrying,
	WebhookEventSagaCompleted,
	WebhookEventSagaFailed,
	WebhookEventSagaCompensating,
	WebhookEventSagaCompensated,
}

// IsValid checks if a webhook event type is valid.
func (t WebhookEventType) IsValid() bool {
	for _, valid := range AllWebhookEventTypes {
		if t == valid {
			return true
		}
	}
	return false
}

// String returns the event type as a string.
func (t WebhookEventType) String() string {
	return string(t)
}

// Webhook represents a webhook subscription for a project.
type Webhook struct {
	ID        WebhookID          `json:"id"`
	ProjectID string             `json:"project_id"`
	URL       string             `json:"url"`
	Secret    string             `json:"-"` // Never expose secret in JSON responses
	Events    []WebhookEventType `json:"events"`
	Enabled   bool               `json:"enabled"`
	CreatedAt time.Time          `json:"created_at"`
	UpdatedAt time.Time          `json:"updated_at"`
}

// HasSecret returns true if the webhook has a signing secret configured.
func (w *Webhook) HasSecret() bool {
	return w.Secret != ""
}

// SubscribesToEvent checks if the webhook subscribes to the given event type.
func (w *Webhook) SubscribesToEvent(eventType WebhookEventType) bool {
	for _, e := range w.Events {
		if e == eventType {
			return true
		}
	}
	return false
}

// WebhookDeliveryID is a strongly-typed identifier for webhook deliveries.
type WebhookDeliveryID string

// String returns the delivery ID as a string.
func (id WebhookDeliveryID) String() string {
	return string(id)
}

// WebhookDelivery represents a single webhook delivery attempt.
type WebhookDelivery struct {
	ID             WebhookDeliveryID `json:"id"`
	WebhookID      WebhookID         `json:"webhook_id"`
	EventType      WebhookEventType  `json:"event_type"`
	Payload        string            `json:"payload"` // JSON payload that was sent
	ResponseStatus int               `json:"response_status,omitempty"`
	ResponseBody   string            `json:"response_body,omitempty"`
	DeliveredAt    time.Time         `json:"delivered_at"`
	Success        bool              `json:"success"`
	RetryCount     int               `json:"retry_count"`
	ErrorMessage   string            `json:"error_message,omitempty"`
}

// WebhookEvent represents an event to be dispatched to webhooks.
type WebhookEvent struct {
	Type      WebhookEventType `json:"type"`
	Timestamp time.Time        `json:"timestamp"`
	ProjectID string           `json:"project_id"`
	Data      any              `json:"data"`
}

// WebhookPayload is the structure sent to webhook endpoints.
type WebhookPayload struct {
	ID        string           `json:"id"`         // Unique delivery ID
	Event     WebhookEventType `json:"event"`      // Event type
	Timestamp time.Time        `json:"timestamp"`  // When the event occurred
	ProjectID string           `json:"project_id"` // Project this event relates to
	Data      any              `json:"data"`       // Event-specific data
}

// CommandEventData is the data structure for command-related webhook events.
type CommandEventData struct {
	CommandID   string      `json:"command_id"`
	CommandType CommandType `json:"command_type"`
	ProjectID   string      `json:"project_id"`
	StartedAt   time.Time   `json:"started_at,omitempty"`
	CompletedAt time.Time   `json:"completed_at,omitempty"`
	ExitCode    int         `json:"exit_code,omitempty"`
	DurationMs  int64       `json:"duration_ms,omitempty"`
	Error       string      `json:"error,omitempty"`
}

// PodEventData is the data structure for pod-related webhook events.
type PodEventData struct {
	PodName   string    `json:"pod_name"`
	ProjectID string    `json:"project_id"`
	Status    string    `json:"status"`
	Reason    string    `json:"reason,omitempty"`
	Message   string    `json:"message,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

// SagaEventData is the data structure for saga-related webhook events.
type SagaEventData struct {
	SagaID     string    `json:"saga_id"`
	SagaName   string    `json:"saga_name"`
	Status     string    `json:"status"`
	StepName   string    `json:"step_name,omitempty"`
	StepStatus string    `json:"step_status,omitempty"`
	RetryCount int       `json:"retry_count,omitempty"`
	Error      string    `json:"error,omitempty"`
	Timestamp  time.Time `json:"timestamp"`
}

// WebhookFilters contains filter options for listing webhook deliveries.
type WebhookDeliveryFilters struct {
	EventType *WebhookEventType // Filter by event type
	Success   *bool             // Filter by success status
	Limit     int               // Max results (default 100)
	Offset    int               // For pagination
}

// DefaultWebhookDeliveryFilters returns sensible defaults.
func DefaultWebhookDeliveryFilters() *WebhookDeliveryFilters {
	return &WebhookDeliveryFilters{
		Limit:  100,
		Offset: 0,
	}
}

// Webhook-related errors are defined in errors.go for centralized error definitions.
