package domain

import (
	"encoding/json"
	"time"

	"github.com/google/uuid"
)

// RuntimeType represents supported function runtimes
type RuntimeType string

const (
	RuntimeNodeJS18 RuntimeType = "nodejs18"
	RuntimePython39 RuntimeType = "python3.9"
	RuntimeGo120    RuntimeType = "go1.20"
	RuntimeCustom   RuntimeType = "custom"
)

// ExecutionStatus represents the status of function execution
type ExecutionStatus string

const (
	StatusPending   ExecutionStatus = "pending"
	StatusRunning   ExecutionStatus = "running"
	StatusCompleted ExecutionStatus = "completed"
	StatusFailed    ExecutionStatus = "failed"
	StatusTimeout   ExecutionStatus = "timeout"
	StatusCanceled  ExecutionStatus = "canceled"
)

// OwnerType represents the type of owner
type OwnerType string

const (
	OwnerTypeIndividual OwnerType = "individual"
	OwnerTypeTeam       OwnerType = "team"
)

// Owner represents ownership information
type Owner struct {
	Type  OwnerType `json:"type" validate:"required,oneof=individual team"`
	Name  string    `json:"name" validate:"required,min=1,max=255"`
	Owner string    `json:"owner" validate:"required,min=1,max=255"`
}

// FunctionDefinition represents a serverless function
type FunctionDefinition struct {
	ID          uuid.UUID         `json:"id" db:"id"`
	Name        string            `json:"name" validate:"required,min=1,max=255" db:"name"`
	AppID       string            `json:"app_id" validate:"required" db:"app_id"`
	Runtime     RuntimeType       `json:"runtime" validate:"required" db:"runtime"`
	Image       string            `json:"image" validate:"required" db:"image"`
	Handler     string            `json:"handler" validate:"required" db:"handler"`
	Code        string            `json:"code,omitempty" db:"code"`
	Environment map[string]string `json:"environment,omitempty" db:"environment"`
	Timeout     Duration          `json:"timeout" validate:"required" db:"timeout"`
	Memory      int               `json:"memory" validate:"required,min=64,max=3008" db:"memory"`
	Owner       Owner             `json:"owner" validate:"required"`
	CreatedAt   time.Time         `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time         `json:"updated_at" db:"updated_at"`
}

// FunctionExecution represents a function execution
type FunctionExecution struct {
	ID          uuid.UUID       `json:"id" db:"id"`
	FunctionID  uuid.UUID       `json:"function_id" db:"function_id"`
	Status      ExecutionStatus `json:"status" db:"status"`
	Input       json.RawMessage `json:"input,omitempty" db:"input"`
	Output      json.RawMessage `json:"output,omitempty" db:"output"`
	Error       string          `json:"error,omitempty" db:"error"`
	Duration    time.Duration   `json:"duration" db:"duration"`
	MemoryUsed  int             `json:"memory_used" db:"memory_used"`
	Logs        []string        `json:"logs,omitempty" db:"logs"`
	ContainerID string          `json:"container_id,omitempty" db:"container_id"`
	ExecutorID  string          `json:"executor_id" db:"executor_id"`
	CreatedAt   time.Time       `json:"created_at" db:"created_at"`
	StartedAt   *time.Time      `json:"started_at,omitempty" db:"started_at"`
	CompletedAt *time.Time      `json:"completed_at,omitempty" db:"completed_at"`
}

// CreateFunctionRequest represents a request to create a new function
type CreateFunctionRequest struct {
	Name        string            `json:"name" validate:"required,min=1,max=255"`
	AppID       string            `json:"app_id" validate:"required"`
	Runtime     RuntimeType       `json:"runtime" validate:"required"`
	Image       string            `json:"image" validate:"required"`
	Handler     string            `json:"handler" validate:"required"`
	Code        string            `json:"code,omitempty"`
	Environment map[string]string `json:"environment,omitempty"`
	Timeout     Duration          `json:"timeout" validate:"required"`
	Memory      int               `json:"memory" validate:"required,min=64,max=3008"`
	Owner       Owner             `json:"owner" validate:"required"`
}

// UpdateFunctionRequest represents a request to update an existing function
type UpdateFunctionRequest struct {
	Name        *string           `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
	Runtime     *RuntimeType      `json:"runtime,omitempty"`
	Image       *string           `json:"image,omitempty"`
	Handler     *string           `json:"handler,omitempty"`
	Code        *string           `json:"code,omitempty"`
	Environment map[string]string `json:"environment,omitempty"`
	Timeout     *Duration         `json:"timeout,omitempty"`
	Memory      *int              `json:"memory,omitempty" validate:"omitempty,min=64,max=3008"`
	Owner       *Owner            `json:"owner,omitempty"`
}

// ExecuteFunctionRequest represents a request to execute a function
type ExecuteFunctionRequest struct {
	FunctionID uuid.UUID       `json:"function_id" validate:"required"`
	Input      json.RawMessage `json:"input,omitempty"`
	Async      bool            `json:"async,omitempty"`
}

// ExecuteFunctionResponse represents a response for function execution
type ExecuteFunctionResponse struct {
	ExecutionID uuid.UUID       `json:"execution_id"`
	Status      ExecutionStatus `json:"status"`
	Output      json.RawMessage `json:"output,omitempty"`
	Error       string          `json:"error,omitempty"`
	Duration    time.Duration   `json:"duration,omitempty"`
	MemoryUsed  int             `json:"memory_used,omitempty"`
}

// DeployFunctionRequest represents a request to deploy a function
type DeployFunctionRequest struct {
	FunctionID uuid.UUID `json:"function_id" validate:"required"`
	Force      bool      `json:"force,omitempty"`
}

// DeployFunctionResponse represents a response for function deployment
type DeployFunctionResponse struct {
	Status  string `json:"status"`
	Message string `json:"message,omitempty"`
	Image   string `json:"image,omitempty"`
	ImageID string `json:"image_id,omitempty"`
}

// RuntimeInfo represents runtime information
type RuntimeInfo struct {
	Type         RuntimeType `json:"type"`
	Version      string      `json:"version"`
	Available    bool        `json:"available"`
	DefaultImage string      `json:"default_image"`
	Description  string      `json:"description"`
}

// ExecutionResult contains function execution results
type ExecutionResult struct {
	Output     json.RawMessage `json:"output,omitempty"`
	Error      string          `json:"error,omitempty"`
	Duration   time.Duration   `json:"duration"`
	MemoryUsed int             `json:"memory_used"`
	Logs       []string        `json:"logs,omitempty"`
}

// AuthContext represents the authentication context for a request
type AuthContext struct {
	UserID      string            `json:"user_id"`
	AppID       string            `json:"app_id"`
	Permissions []string          `json:"permissions"`
	Claims      map[string]string `json:"claims"`
}
