package models

import (
	"encoding/json"
	"time"

	"gorm.io/gorm"
)

type App struct {
	ID          string `json:"id" gorm:"primaryKey"`
	Name        string `json:"name" gorm:"not null"`
	Description string `json:"description"`
	Type        string `json:"type" gorm:"index"` // frontend, backend, api, database, or microservice
	Language    string `json:"language"`          // Programming language or framework
	Version     string `json:"version"`           // Version number (e.g., 1.0.0)

	// Configuration details
	ConfigFile   string `json:"configFile" gorm:"type:text"`   // JSON configuration as a string
	EnvVariables string `json:"envVariables" gorm:"type:text"` // Environment variables as a string

	// Source code details
	Repository   string `json:"repository"`                   // Git repository URL
	Branch       string `json:"branch" gorm:"default:'main'"` // Git branch (default: main)
	BuildCommand string `json:"buildCommand"`                 // Command to build the app

	// Resource allocation - stored as JSON
	ResourcesJSON     string `json:"-" gorm:"column:resources;type:text"`
	ScaleSettingsJSON string `json:"-" gorm:"column:scale_settings;type:text"`

	// Virtual fields for ORM serialization/deserialization
	Resources     ResourceRequirements `json:"resources" gorm:"-"`
	ScaleSettings ScaleSettings        `json:"scaleSettings" gorm:"-"`

	CreatedAt time.Time      `json:"createdAt" gorm:"autoCreateTime"`
	UpdatedAt time.Time      `json:"updatedAt" gorm:"autoUpdateTime"`
	CreatedBy string         `json:"createdBy" gorm:"index"` // User ID who created the app
	DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`         // Soft delete support

	// Relationships
	Deployments []DeployedApp `json:"deployments" gorm:"foreignKey:AppID"` // Apps deployed in deployments
}

type ResourceRequirements struct {
	CPU     string `json:"cpu"`     // e.g., "0.5"
	Memory  string `json:"memory"`  // e.g., "512Mi"
	Storage string `json:"storage"` // e.g., "1Gi"
}

type ScaleSettings struct {
	MinInstances int `json:"minInstances"` // Minimum number of instances
	MaxInstances int `json:"maxInstances"` // Maximum number of instances
	CPUThreshold int `json:"cpuThreshold"` // CPU threshold for scaling (percentage)
}

// AppType represents the type of application
type AppType string

const (
	Frontend     AppType = "frontend"
	Backend      AppType = "backend"
	API          AppType = "api"
	Database     AppType = "database"
	Microservice AppType = "microservice"
)

// BeforeSave serializes the embedded JSON fields
func (a *App) BeforeSave(tx *gorm.DB) error {
	var err error

	// Marshal Resources to JSON
	resourcesJSON, err := json.Marshal(a.Resources)
	if err != nil {
		return err
	}
	a.ResourcesJSON = string(resourcesJSON)

	// Marshal ScaleSettings to JSON
	scaleSettingsJSON, err := json.Marshal(a.ScaleSettings)
	if err != nil {
		return err
	}
	a.ScaleSettingsJSON = string(scaleSettingsJSON)

	return nil
}

// AfterFind deserializes the JSON fields
func (a *App) AfterFind(tx *gorm.DB) error {
	// Unmarshal Resources from JSON
	if a.ResourcesJSON != "" {
		if err := json.Unmarshal([]byte(a.ResourcesJSON), &a.Resources); err != nil {
			return err
		}
	}

	// Unmarshal ScaleSettings from JSON
	if a.ScaleSettingsJSON != "" {
		if err := json.Unmarshal([]byte(a.ScaleSettingsJSON), &a.ScaleSettings); err != nil {
			return err
		}
	}

	return nil
}
