// Filename: internal/models/models.go
package models

import (
	"time"

	"gorm.io/datatypes"
	"gorm.io/gorm"
)

// ========= 自定义类型和常量 =========
type APIKeyStatus string
type MasterAPIKeyStatus string
type PollingStrategy string
type FileProcessingState string
type LogType string
type ProtocolType string

const (
	// --- 运营状态 (在中间表中使用) ---
	StatusPendingValidation APIKeyStatus = "PENDING_VALIDATION"
	StatusActive            APIKeyStatus = "ACTIVE"
	StatusCooldown          APIKeyStatus = "COOLDOWN"
	StatusDisabled          APIKeyStatus = "DISABLED"
	StatusBanned            APIKeyStatus = "BANNED"

	// --- 身份状态 (在APIKey实体中使用) ---
	MasterStatusActive           MasterAPIKeyStatus = "ACTIVE"            // 有效
	MasterStatusRevoked          MasterAPIKeyStatus = "REVOKED"           // 永久吊销
	MasterStatusManuallyDisabled MasterAPIKeyStatus = "MANUALLY_DISABLED" // 手动全局禁用

	StrategyWeighted   PollingStrategy     = "weighted"
	StrategySequential PollingStrategy     = "sequential"
	StrategyRandom     PollingStrategy     = "random"
	FileProcessing     FileProcessingState = "PROCESSING"
	FileActive         FileProcessingState = "ACTIVE"
	FileFailed         FileProcessingState = "FAILED"

	LogTypeFinal      LogType = "FINAL" // Represents the final outcome of a request, including all retries.
	LogTypeRetry      LogType = "RETRY" // Represents a single, failed attempt that triggered a retry.
	LogTypeValidation LogType = "VALIDATION"

	ProtocolOpenAI ProtocolType = "openai"
	ProtocolGemini ProtocolType = "gemini"
)

// ========= 核心数据库模型 =========
type KeyGroup struct {
	ID               uint `gorm:"primarykey"`
	CreatedAt        time.Time
	UpdatedAt        time.Time
	Name             string          `gorm:"type:varchar(100);unique;not null"`
	DisplayName      string          `gorm:"type:varchar(255)"`
	Description      string          `gorm:"type:text"`
	PollingStrategy  PollingStrategy `gorm:"type:varchar(20);not null;default:sequential"`
	EnableProxy      bool            `gorm:"not null;default:false"`
	Sort             int             `gorm:"default:0"` // 用于业务逻辑排序 (保留)
	Order            int             `gorm:"default:0"` // 专用于UI拖拽排序
	LastValidatedAt  *time.Time
	Mappings         []*GroupAPIKeyMapping `gorm:"foreignKey:KeyGroupID"`
	AllowedModels    []*GroupModelMapping  `gorm:"foreignKey:GroupID"`
	AllowedUpstreams []*UpstreamEndpoint   `gorm:"many2many:group_upstream_access;"`
	ChannelType      string                `gorm:"type:varchar(50);not null;default:'gemini'"`
	Settings         *GroupSettings        `gorm:"foreignKey:GroupID"`
	RequestConfigID  *uint                 `json:"request_config_id"`
	RequestConfig    *RequestConfig        `gorm:"foreignKey:RequestConfigID"`
}

type APIKey struct {
	ID           uint `gorm:"primarykey"`
	CreatedAt    time.Time
	UpdatedAt    time.Time
	DeletedAt    gorm.DeletedAt        `gorm:"index"`
	EncryptedKey string                `gorm:"type:text;not null"`
	APIKeyHash   string                `gorm:"type:varchar(64);unique;not null;index"`
	MaskedKey    string                `gorm:"type:varchar(50);index"`
	MasterStatus MasterAPIKeyStatus    `gorm:"type:varchar(25);not null;default:ACTIVE;index"`
	ProxyID      *uint                 `gorm:"index"`
	Mappings     []*GroupAPIKeyMapping `gorm:"foreignKey:APIKeyID"`
	APIKey       string                `gorm:"-"`
}

// GroupAPIKeyMapping 承载 “运营状态”
type GroupAPIKeyMapping struct {
	KeyGroupID            uint         `gorm:"primaryKey"`
	APIKeyID              uint         `gorm:"primaryKey"`
	Status                APIKeyStatus `gorm:"type:varchar(25);not null;default:PENDING_VALIDATION;index"`
	LastError             string       `gorm:"type:text"`
	ConsecutiveErrorCount int          `gorm:"not null;default:0"`
	LastUsedAt            *time.Time
	CooldownUntil         *time.Time
	CreatedAt             time.Time
	UpdatedAt             time.Time
	APIKey                *APIKey   `gorm:"foreignKey:APIKeyID"`
	KeyGroup              *KeyGroup `gorm:"foreignKey:KeyGroupID"`
}

type RequestLog struct {
	ID               uint      `gorm:"primarykey"`
	RequestTime      time.Time `gorm:"index"`
	LatencyMs        int
	IsSuccess        bool
	StatusCode       int
	Status           string `gorm:"type:varchar(100);index"`
	ModelName        string `gorm:"type:varchar(100);index"`
	GroupID          *uint  `gorm:"index"`
	KeyID            *uint  `gorm:"index"`
	AuthTokenID      *uint
	UpstreamID       *uint
	ProxyID          *uint
	Retries          int               `gorm:"not null;default:0"`
	ErrorCode        string            `gorm:"type:varchar(50);index"`
	ErrorMessage     string            `gorm:"type:text"`
	RequestPath      string            `gorm:"type:varchar(500)"`
	UserAgent        string            `gorm:"type:varchar(512)"`
	PromptTokens     int               `gorm:"not null;default:0"`
	CompletionTokens int               `gorm:"not null;default:0"`
	CorrelationID    string            `gorm:"type:varchar(36);index"`
	LogType          LogType           `gorm:"type:varchar(20);index"`
	Metadata         datatypes.JSONMap `gorm:"type:json"`
}

// GroupModelMapping 模型关系表
type GroupModelMapping struct {
	ID        uint   `gorm:"primarykey"`
	GroupID   uint   `gorm:"index;uniqueIndex:idx_group_model_unique"`
	ModelName string `gorm:"type:varchar(100);not null;uniqueIndex:idx_group_model_unique"`
}

// AuthToken
type AuthToken struct {
	ID                    uint `gorm:"primarykey"`
	CreatedAt             time.Time
	UpdatedAt             time.Time
	EncryptedToken        string      `gorm:"type:text;not null"`
	TokenHash             string      `gorm:"type:varchar(64);unique;not null;index"`
	Token                 string      `gorm:"-"`
	Description           string      `gorm:"type:text"`
	Tag                   string      `gorm:"type:varchar(100);index"`
	IsAdmin               bool        `gorm:"not null;default:false"`
	HasUnrestrictedAccess bool        `gorm:"not null;default:false"`
	Status                string      `gorm:"type:varchar(20);not null;default:active"`
	AllowedGroups         []*KeyGroup `gorm:"many2many:token_group_access;"`
}

// FileRecord
type FileRecord struct {
	ID             uint `gorm:"primarykey"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
	KeyID          uint                `gorm:"not null"`
	Name           string              `gorm:"type:varchar(255);unique;not null"`
	DisplayName    string              `gorm:"type:varchar(255)"`
	MimeType       string              `gorm:"type:varchar(100);not null"`
	SizeBytes      int64               `gorm:"not null"`
	Sha256Hash     string              `gorm:"type:varchar(64)"`
	State          FileProcessingState `gorm:"type:varchar(20);not null;default:PROCESSING"`
	Uri            string              `gorm:"type:varchar(500);not null"`
	ExpirationTime time.Time           `gorm:"not null"`
}

// StatsHourly 长期历史数据仓库，为趋势分析提供高效查询
type StatsHourly struct {
	ID               uint      `gorm:"primarykey"`
	Time             time.Time `gorm:"uniqueIndex:idx_stats_hourly_unique"`
	GroupID          uint      `gorm:"uniqueIndex:idx_stats_hourly_unique"`
	ModelName        string    `gorm:"type:varchar(100);uniqueIndex:idx_stats_hourly_unique"`
	RequestCount     int64     `gorm:"not null;default:0"`
	SuccessCount     int64     `gorm:"not null;default:0"`
	PromptTokens     int64     `gorm:"not null;default:0"`
	CompletionTokens int64     `gorm:"not null;default:0"`
}

type UpstreamEndpoint struct {
	ID          uint `gorm:"primarykey"`
	CreatedAt   time.Time
	UpdatedAt   time.Time
	URL         string `gorm:"type:varchar(500);unique;not null"`
	Weight      int    `gorm:"not null;default:100;index"`
	Status      string `gorm:"type:varchar(20);not null;default:'active';index"`
	Description string `gorm:"type:text"`
}
type ProxyConfig struct {
	ID                uint `gorm:"primarykey"`
	CreatedAt         time.Time
	UpdatedAt         time.Time
	Address           string `gorm:"type:varchar(255);unique;not null"`
	Protocol          string `gorm:"type:varchar(10);not null"`
	Status            string `gorm:"type:varchar(20);not null;default:'active';index"`
	AssignedKeysCount int    `gorm:"not null;default:0;index"`
	Description       string `gorm:"type:text"`
}
type Setting struct {
	Key          string `gorm:"primarykey;type:varchar(100)" json:"key"`
	Value        string `gorm:"type:text" json:"value"`
	Name         string `gorm:"type:varchar(100)" json:"name"`
	Description  string `gorm:"type:varchar(255)" json:"description"`
	Type         string `gorm:"type:varchar(20)" json:"type"`
	Category     string `gorm:"type:varchar(50);index" json:"category"`
	DefaultValue string `gorm:"type:text" json:"default_value"`
}

// GroupSettings 用于存储特定于Group的配置覆盖
type GroupSettings struct {
	GroupID      uint           `gorm:"primaryKey"`
	SettingsJSON datatypes.JSON `gorm:"type:json"` // 将 KeyGroupSettings 序列化后存入此字段
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

// KeyGroupSettings 定义可以被分组覆盖的所有**运营**配置项
// 不会直接映射到数据库表，作为 JSON 对象存储在 GroupSettings.SettingsJSON
type KeyGroupSettings struct {
	// 健康检查相关配置
	EnableKeyCheck          *bool   `json:"enable_key_check,omitempty"`
	KeyCheckModel           *string `json:"key_check_model,omitempty"`
	KeyCheckEndpoint        *string `json:"key_check_endpoint,omitempty"`
	KeyCheckConcurrency     *int    `json:"key_check_concurrency,omitempty"`
	KeyCheckIntervalMinutes *int    `json:"key_check_interval_minutes,omitempty"`
	// 惩罚机制相关配置
	KeyBlacklistThreshold *int `json:"key_blacklist_threshold,omitempty"`
	KeyCooldownMinutes    *int `json:"key_cooldown_minutes,omitempty"`
	MaxRetries            *int `json:"max_retries,omitempty"`
	// Smart Gateway
	EnableSmartGateway *bool `json:"enable_smart_gateway,omitempty"`
}

// RequestConfig 封装了所有直接影响对上游API请求的参数，作为一个独立的数据库模型
type RequestConfig struct {
	ID uint `gorm:"primarykey"`
	//Custom Headers
	CustomHeaders datatypes.JSONMap `gorm:"type:json" json:"custom_headers"`

	// Streaming Optimization
	EnableStreamOptimizer bool `json:"enable_stream_optimizer"`
	StreamMinDelay        int  `json:"stream_min_delay"`
	StreamMaxDelay        int  `json:"stream_max_delay"`
	StreamShortTextThresh int  `json:"stream_short_text_thresh"`
	StreamLongTextThresh  int  `json:"stream_long_text_thresh"`
	StreamChunkSize       int  `json:"stream_chunk_size"`
	EnableFakeStream      bool `json:"enable_fake_stream"`
	FakeStreamInterval    int  `json:"fake_stream_interval"`

	// Model and Safety Settings
	ModelSettings datatypes.JSON `gorm:"type:json" json:"model_settings"`

	// Generic Overrides for parameters not explicitly defined
	ConfigOverrides datatypes.JSONMap `gorm:"type:json" json:"config_overrides"`

	CreatedAt time.Time
	UpdatedAt time.Time
}
