package models

import (
	"time"

	"gorm.io/gorm"
)

// Deployment represents a deployed instance of an application
type Deployment struct {
	ID          string `json:"id" gorm:"primaryKey"` // Unique identifier
	Name        string `json:"name" gorm:"not null"` // Deployment name
	Description string `json:"description"`          // Deployment description

	// Core relationships
	BlueprintID string `json:"blueprintId" gorm:"index"` // Reference to the blueprint being deployed
	ClientID    string `json:"clientId" gorm:"index"`    // Client this deployment belongs to

	// Infrastructure details
	Provider     string `json:"provider"`                        // Cloud provider (aws, gcp, azure, etc.)
	InstanceID   string `json:"instanceId"`                      // ID of the provisioned instance
	InstanceType string `json:"instanceType"`                    // Type/size of instance
	ImageID      string `json:"imageId"`                         // Image ID used for the instance
	IPAddress    string `json:"ipAddress"`                       // IP address of the instance
	IsFromPool   bool   `json:"isFromPool" gorm:"default:false"` // Whether this instance came from the pool

	// Status and environment
	Status      string `json:"status" gorm:"default:'pending'"`          // Current deployment status
	Environment string `json:"environment" gorm:"default:'development'"` // dev, staging, production
	Region      string `json:"region"`                                   // Geographic region

	// Deployment configuration
	Hostname     string `json:"hostname"`     // External hostname for the deployment
	CustomDomain string `json:"customDomain"` // Custom domain if configured

	// Operational data
	LogsConfig    string `json:"logsConfig" gorm:"type:text"`    // Logging configuration as JSON
	MetricsConfig string `json:"metricsConfig" gorm:"type:text"` // Metrics configuration as JSON
	AlertsConfig  string `json:"alertsConfig" gorm:"type:text"`  // Alert configurations as JSON

	CreatedAt      time.Time      `json:"createdAt" gorm:"autoCreateTime"` // Creation timestamp
	UpdatedAt      time.Time      `json:"updatedAt" gorm:"autoUpdateTime"` // Last update timestamp
	LastDeployedAt time.Time      `json:"lastDeployedAt"`                  // When the deployment was last deployed
	CreatedBy      string         `json:"createdBy" gorm:"index"`          // User ID who created the deployment
	DeletedAt      gorm.DeletedAt `json:"-" gorm:"index"`                  // Soft delete support

	// GORM relationships
	DeployedComponents []DeployedComponent `json:"deployedComponents" gorm:"foreignKey:DeploymentID"` // Array of deployed components
}

// DeployedComponent represents a specific component within a deployment
type DeployedComponent struct {
	ID             string         `json:"id" gorm:"primaryKey"`                  // Unique identifier
	DeploymentID   string         `json:"deploymentId" gorm:"index"`             // Reference to the parent deployment
	ComponentID    string         `json:"componentId" gorm:"index"`              // Reference to the component being deployed
	Status         string         `json:"status" gorm:"default:'pending'"`       // Status of this specific app's deployment
	Version        string         `json:"version"`                               // Deployed version
	URL            string         `json:"url"`                                   // URL to access this app
	PodCount       int            `json:"podCount" gorm:"default:1"`             // Number of running instances/pods
	HealthStatus   string         `json:"healthStatus" gorm:"default:'pending'"` // Current health status
	ConfigSnapshot string         `json:"configSnapshot" gorm:"type:text"`       // Snapshot of configuration at deployment time
	CreatedAt      time.Time      `json:"createdAt" gorm:"autoCreateTime"`       // Creation timestamp
	UpdatedAt      time.Time      `json:"updatedAt" gorm:"autoUpdateTime"`       // Last update timestamp
	DeletedAt      gorm.DeletedAt `json:"-" gorm:"index"`                        // Soft delete support

	// GORM relationships - these will be serialized/deserialized as JSON
	Resources ResourceAllocation `json:"resources" gorm:"-"` // Actual resources allocated
}

// Component resource allocation (will be stored in DeployedComponentResource table)
type DeployedComponentResource struct {
	ID                  string    `json:"id" gorm:"primaryKey"`                   // Unique identifier
	DeployedComponentID string    `json:"deployedComponentId" gorm:"uniqueIndex"` // Reference to deployed component
	CPU                 string    `json:"cpu"`                                    // Allocated CPU
	CPUUsage            float64   `json:"cpuUsage"`                               // Current CPU usage percentage
	Memory              string    `json:"memory"`                                 // Allocated memory
	MemoryUsage         float64   `json:"memoryUsage"`                            // Current memory usage percentage
	Storage             string    `json:"storage"`                                // Allocated storage
	StorageUsage        float64   `json:"storageUsage"`                           // Current storage usage percentage
	LastUpdated         time.Time `json:"lastUpdated" gorm:"autoUpdateTime"`      // When metrics were last updated
}

// For backward compatibility
type ResourceAllocation struct {
	CPU          string  `json:"cpu"`          // Allocated CPU
	CPUUsage     float64 `json:"cpuUsage"`     // Current CPU usage percentage
	Memory       string  `json:"memory"`       // Allocated memory
	MemoryUsage  float64 `json:"memoryUsage"`  // Current memory usage percentage
	Storage      string  `json:"storage"`      // Allocated storage
	StorageUsage float64 `json:"storageUsage"` // Current storage usage percentage
}

// LogConfiguration, MetricsConfiguration, and AlertConfiguration remain the same
// These will be serialized/deserialized as JSON

type LogConfiguration struct {
	Enabled       bool   `json:"enabled"`       // Whether logging is enabled
	RetentionDays int    `json:"retentionDays"` // Number of days to retain logs
	ExternalSink  string `json:"externalSink"`  // External logging system URL if any
}

type MetricsConfiguration struct {
	Enabled       bool     `json:"enabled"`       // Whether metrics collection is enabled
	RetentionDays int      `json:"retentionDays"` // Number of days to retain metrics
	CustomMetrics []string `json:"customMetrics"` // Any custom metrics to collect
}

type AlertConfiguration struct {
	Type                 string   `json:"type"`                 // Type of alert
	Threshold            float64  `json:"threshold"`            // Threshold value
	Operator             string   `json:"operator"`             // ">", "<", ">=", "<=", "=="
	Duration             string   `json:"duration"`             // How long condition must be true before alerting
	NotificationChannels []string `json:"notificationChannels"` // Channels to notify (email, slack, etc.)
}

// DeploymentStatus type definitions
type DeploymentStatus string
type Environment string
type ComponentDeploymentStatus string
type HealthStatus string
type AlertType string

const (
	// DeploymentStatus values
	PENDING_DEPLOYMENT  DeploymentStatus = "pending"
	DEPLOYING           DeploymentStatus = "deploying"
	DEPLOYED            DeploymentStatus = "deployed"
	FAILED_DEPLOYMENT   DeploymentStatus = "failed"
	UPDATING_DEPLOYMENT DeploymentStatus = "updating"
	DELETING            DeploymentStatus = "deleting"

	// Environment values
	DEVELOPMENT Environment = "development"
	STAGING     Environment = "staging"
	PRODUCTION  Environment = "production"

	// ComponentDeploymentStatus values
	PENDING_APP  ComponentDeploymentStatus = "pending"
	RUNNING      ComponentDeploymentStatus = "running"
	FAILED_APP   ComponentDeploymentStatus = "failed"
	SCALING      ComponentDeploymentStatus = "scaling"
	UPDATING_APP ComponentDeploymentStatus = "updating"

	// HealthStatus values
	HEALTHY   HealthStatus = "healthy"
	DEGRADED  HealthStatus = "degraded"
	UNHEALTHY HealthStatus = "unhealthy"

	// AlertType values
	CPU_USAGE    AlertType = "cpu_usage"
	MEMORY_USAGE AlertType = "memory_usage"
	DISK_USAGE   AlertType = "disk_usage"
	ERROR_RATE   AlertType = "error_rate"
	LATENCY      AlertType = "latency"
)
