package model

import (
	"time"
)

type ProviderType string

const (
	ProviderOpenAI     ProviderType = "openai"
	ProviderAnthropic  ProviderType = "anthropic"
	ProviderCustom     ProviderType = "custom"
	ProviderAzureOpenAI ProviderType = "azure_openai"
	ProviderOpenRouter ProviderType = "openrouter"
	ProviderOllama     ProviderType = "ollama"
	ProviderComfyUI  ProviderType = "comfyui"
)

type WorkflowType string

const (
	WorkflowTxt2Img WorkflowType = "txt2img"
	WorkflowImg2Img WorkflowType = "img2img"
)

type PredictionStatus string

const (
	PredictionStarting   PredictionStatus = "starting"
	PredictionProcessing PredictionStatus = "processing"
	PredictionSucceeded  PredictionStatus = "succeeded"
	PredictionFailed     PredictionStatus = "failed"
	PredictionCanceled   PredictionStatus = "canceled"
)

type ProviderStatus string

const (
	ProviderHealthy   ProviderStatus = "healthy"
	ProviderUnhealthy ProviderStatus = "unhealthy"
	ProviderUnknown   ProviderStatus = "unknown"
)

type Provider struct {
	ID                   uint             `gorm:"primaryKey" json:"id"`
	Name                 string           `gorm:"uniqueIndex;not null" json:"name"`
	Type                 ProviderType     `gorm:"not null" json:"type"`
	Category             ProviderCategory `gorm:"not null;default:llm" json:"category"`
	BaseURL              string           `json:"base_url"`
	AllowedEndpointsJSON string           `gorm:"default:'[\"list_models\",\"chat_completion\"]'" json:"allowed_endpoints_json"`
	EndpointPathsJSON    string           `gorm:"default:'{}'" json:"endpoint_paths_json"`
	Status               ProviderStatus   `gorm:"default:unknown" json:"status"`
	Enabled              bool             `gorm:"default:true" json:"enabled"`
	CreatedAt            time.Time        `json:"created_at"`
	UpdatedAt            time.Time        `json:"updated_at"`
	Keys                 []ProviderKey    `gorm:"foreignKey:ProviderID" json:"keys,omitempty"`
	Models               []ModelEntry     `gorm:"foreignKey:ProviderID" json:"models,omitempty"`
}

type ProviderKey struct {
	ID               uint      `gorm:"primaryKey" json:"id"`
	ProviderID       uint      `gorm:"index;not null" json:"provider_id"`
	Name             string    `gorm:"not null" json:"name"`
	APIKeyEnc        string    `gorm:"not null" json:"-"`
	Weight           float64   `gorm:"default:1" json:"weight"`
	ModelsJSON       string    `gorm:"default:'[\"*\"]'" json:"models_json"`
	Enabled          bool      `gorm:"default:true" json:"enabled"`
	MaxRequestsPerDay int      `gorm:"default:0" json:"max_requests_per_day"`
	MaxTokensPerDay   int64    `gorm:"default:0" json:"max_tokens_per_day"`
	RequestsToday     int      `gorm:"default:0" json:"requests_today"`
	TokensToday       int64    `gorm:"default:0" json:"tokens_today"`
	CreatedAt        time.Time `json:"created_at"`
	UpdatedAt        time.Time `json:"updated_at"`
}

type ModelEntry struct {
	ID                uint         `gorm:"primaryKey" json:"id"`
	ProviderID        uint         `gorm:"index;not null" json:"provider_id"`
	ModelID           string       `gorm:"not null" json:"model_id"`
	Alias             string       `gorm:"index" json:"alias"`
	DisplayName       string       `json:"display_name"`
	WorkflowType      WorkflowType `gorm:"default:txt2img" json:"workflow_type"`
	WorkflowJSON      string       `gorm:"type:text" json:"workflow_json"`
	InputBindingJSON  string       `gorm:"type:text" json:"input_binding_json"`
	VersionHash       string       `gorm:"index" json:"version_hash"`
	Enabled           bool         `gorm:"default:true" json:"enabled"`
	CreatedAt         time.Time    `json:"created_at"`
}

type IngressKey struct {
	ID                   uint               `gorm:"primaryKey" json:"id"`
	Name                 string             `gorm:"not null" json:"name"`
	KeyHash              string             `gorm:"uniqueIndex;not null" json:"-"`
	Prefix               string             `gorm:"not null" json:"prefix"`
	Protocol             IngressKeyProtocol `gorm:"not null;default:text" json:"protocol"`
	Enabled              bool               `gorm:"default:true" json:"enabled"`
	BudgetLimit          float64    `gorm:"default:0" json:"budget_limit"`
	BudgetUsed           float64    `gorm:"default:0" json:"budget_used"`
	RateLimitRPM         int        `gorm:"default:0" json:"rate_limit_rpm"`
	RateLimitTPM         int        `gorm:"default:0" json:"rate_limit_tpm"`
	AllowedProvidersJSON string     `gorm:"default:'[\"*\"]'" json:"allowed_providers_json"`
	AllowedModelsJSON    string     `gorm:"default:'[\"*\"]'" json:"allowed_models_json"`
	RequestCount         int64      `gorm:"default:0" json:"request_count"`
	TokenCount           int64      `gorm:"default:0" json:"token_count"`
	ExpiresAt            *time.Time `json:"expires_at"`
	CreatedAt            time.Time  `json:"created_at"`
	UpdatedAt            time.Time  `json:"updated_at"`
}

type AdminUser struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	Username     string    `gorm:"uniqueIndex;not null" json:"username"`
	PasswordHash string    `gorm:"not null" json:"-"`
	CreatedAt    time.Time `json:"created_at"`
}

type AdminSession struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	TokenHash string    `gorm:"uniqueIndex;not null" json:"-"`
	ExpiresAt time.Time `gorm:"index" json:"expires_at"`
	CreatedAt time.Time `json:"created_at"`
}

type IPRuleType string

const (
	IPRuleAllow IPRuleType = "allow"
	IPRuleDeny  IPRuleType = "deny"
)

type IPRuleScope string

const (
	IPScopeAdmin IPRuleScope = "admin"
	IPScopeProxy IPRuleScope = "proxy"
	IPScopeAll   IPRuleScope = "all"
)

type IPRule struct {
	ID        uint        `gorm:"primaryKey" json:"id"`
	CIDR      string      `gorm:"column:cidr;not null" json:"cidr"`
	Type      IPRuleType  `gorm:"not null" json:"type"`
	Scope     IPRuleScope `gorm:"not null;default:proxy" json:"scope"`
	Enabled   bool        `gorm:"default:true" json:"enabled"`
	CreatedAt time.Time   `json:"created_at"`
}

type UsageRecord struct {
	ID            uint      `gorm:"primaryKey" json:"id"`
	IngressKeyID  uint      `gorm:"index" json:"ingress_key_id"`
	ProviderID    uint      `gorm:"index" json:"provider_id"`
	ProviderKeyID uint      `gorm:"index" json:"provider_key_id"`
	ClientIP      string    `gorm:"index" json:"client_ip"`
	Endpoint      string    `json:"endpoint"`
	Model         string    `json:"model"`
	TokensIn      int       `json:"tokens_in"`
	TokensOut     int       `json:"tokens_out"`
	Cost          float64   `json:"cost"`
	LatencyMs     int64     `json:"latency_ms"`
	Status        string    `json:"status"`
	Stream        bool      `json:"stream"`
	ErrorMsg      string    `json:"error_msg"`
	RequestBody   string    `gorm:"type:text" json:"request_body,omitempty"`
	ResponseBody  string    `gorm:"type:text" json:"response_body,omitempty"`
	CreatedAt     time.Time `gorm:"index" json:"created_at"`
}

const (
	MaxUsageLogRecords = 500
	EndpointAdminLogin = "admin_login"
	EndpointPrediction = "prediction"
)

type Prediction struct {
	ID            string           `gorm:"primaryKey" json:"id"`
	IngressKeyID  uint             `gorm:"index;not null" json:"ingress_key_id"`
	ProviderID    uint             `gorm:"index;not null" json:"provider_id"`
	ProviderKeyID uint             `gorm:"index" json:"provider_key_id"`
	ModelEntryID  uint             `gorm:"index" json:"model_entry_id"`
	Version       string           `json:"version"`
	Model         string           `json:"model"`
	InputJSON     string           `gorm:"type:text" json:"input_json"`
	Status        PredictionStatus `gorm:"index;not null;default:starting" json:"status"`
	ComfyPromptID string           `json:"comfy_prompt_id"`
	ClientID      string           `json:"client_id"`
	OutputJSON    string           `gorm:"type:text" json:"output_json"`
	Error         string           `gorm:"type:text" json:"error"`
	Logs          string           `gorm:"type:text" json:"logs"`
	MetricsJSON   string           `gorm:"type:text" json:"metrics_json"`
	CreatedAt     time.Time        `json:"created_at"`
	StartedAt     *time.Time       `json:"started_at"`
	CompletedAt   *time.Time       `json:"completed_at"`
}

type StoredImage struct {
	ID           string    `gorm:"primaryKey" json:"id"`
	PredictionID string    `gorm:"index;not null" json:"prediction_id"`
	Filename     string    `json:"filename"`
	LocalPath    string    `json:"-"`
	Mime         string    `json:"mime"`
	Size         int64     `json:"size"`
	CreatedAt    time.Time `json:"created_at"`
}

// RoutingRule Virtual Key 路由：按模型匹配绑定 Provider / ProviderKey
type RoutingRule struct {
	ID            uint      `gorm:"primaryKey" json:"id"`
	IngressKeyID  uint      `gorm:"index;not null" json:"ingress_key_id"`
	ModelPattern  string    `gorm:"not null" json:"model_pattern"`
	ProviderID    uint      `gorm:"not null" json:"provider_id"`
	ProviderKeyID uint      `gorm:"default:0" json:"provider_key_id"`
	Priority      int       `gorm:"default:0" json:"priority"`
	Enabled       bool      `gorm:"default:true" json:"enabled"`
	CreatedAt     time.Time `json:"created_at"`
}

// SystemSettings singleton (id=1) for runtime configuration managed via admin UI.
type SystemSettings struct {
	ID                    uint      `gorm:"primaryKey" json:"id"`
	EncryptionKey         string    `gorm:"not null" json:"-"`
	SessionTTLSeconds     int64     `gorm:"not null;default:86400" json:"session_ttl_seconds"`
	LoginMaxAttempts      int       `gorm:"not null;default:5" json:"login_max_attempts"`
	LoginLockoutSeconds   int64     `gorm:"not null;default:900" json:"login_lockout_seconds"`
	TrustedProxiesJSON    string    `gorm:"default:'[]'" json:"trusted_proxies_json"`
	UsageFlushSeconds     int64     `gorm:"not null;default:5" json:"usage_flush_seconds"`
	HealthCheckSeconds    int64     `gorm:"not null;default:30" json:"health_check_seconds"`
	GatewayMaxRetries     int       `gorm:"not null;default:3" json:"gateway_max_retries"`
	GatewayRetryBackoffMs int       `gorm:"not null;default:200" json:"gateway_retry_backoff_ms"`
	ImageStoragePath      string    `gorm:"default:'images'" json:"image_storage_path"`
	PublicBaseURL         string    `json:"public_base_url"`
	SignedURLTTLSeconds   int64     `gorm:"not null;default:3600" json:"signed_url_ttl_seconds"`
	PredictionWaitSeconds int64     `gorm:"not null;default:60" json:"prediction_wait_seconds"`
	CreatedAt             time.Time `json:"created_at"`
	UpdatedAt             time.Time `json:"updated_at"`
}

type HealthCheckRecord struct {
	ID         uint           `gorm:"primaryKey" json:"id"`
	ProviderID uint           `gorm:"index" json:"provider_id"`
	Status     ProviderStatus `json:"status"`
	LatencyMs  int64          `json:"latency_ms"`
	ErrorMsg   string         `json:"error_msg"`
	CheckedAt  time.Time      `gorm:"index" json:"checked_at"`
}
