package models

import (
	"time"

	"gorm.io/gorm"
)

// AIModel represents an AI model configuration
type AIModel struct {
	ID          uint           `json:"id" gorm:"primaryKey"`
	Name        string         `json:"name" gorm:"not null"`
	Type        string         `json:"type" gorm:"not null"` // 'openai', 'local', 'custom'
	Endpoint    string         `json:"endpoint"`
	APIKey      string         `json:"apiKey"` // Encrypted in database
	Model       string         `json:"model"`  // e.g., 'gpt-4', 'llama2', etc.
	MaxTokens   int            `json:"maxTokens" gorm:"default:1000"`
	Temperature float64        `json:"temperature" gorm:"default:0.7"`
	TopP        float64        `json:"topP" gorm:"default:1.0"`
	Active      bool           `json:"active" gorm:"default:true"`
	Priority    int            `json:"priority" gorm:"default:1"` // Higher number = higher priority
	Description string         `json:"description"`
	CreatedAt   time.Time      `json:"createdAt"`
	UpdatedAt   time.Time      `json:"updatedAt"`
	DeletedAt   gorm.DeletedAt `json:"-" gorm:"index"`
}

// AIInteraction represents an interaction with an AI model
type AIInteraction struct {
	ID             uint      `json:"id" gorm:"primaryKey"`
	ConversationID uint      `json:"conversationId"`
	MessageID      uint      `json:"messageId"`
	AIModelID      uint      `json:"aiModelId"`
	Prompt         string    `json:"prompt" gorm:"not null"`
	Response       string    `json:"response" gorm:"not null"`
	TokensUsed     int       `json:"tokensUsed"`
	ResponseTime   int64     `json:"responseTime"` // in milliseconds
	Cost           float64   `json:"cost"`
	Success        bool      `json:"success"`
	ErrorMessage   string    `json:"errorMessage"`
	CreatedAt      time.Time `json:"createdAt"`

	// Relationships
	Conversation Conversation `json:"conversation" gorm:"foreignKey:ConversationID"`
	Message      Message      `json:"message" gorm:"foreignKey:MessageID"`
	AIModel      AIModel      `json:"aiModel" gorm:"foreignKey:AIModelID"`
}

// AIFallback represents a fallback event when an AI model fails
type AIFallback struct {
	ID             uint      `json:"id" gorm:"primaryKey"`
	ConversationID uint      `json:"conversationId"`
	MessageID      uint      `json:"messageId"`
	FromAIModelID  uint      `json:"fromAiModelId"`
	ToAIModelID    uint      `json:"toAiModelId"`
	Reason         string    `json:"reason" gorm:"not null"`
	CreatedAt      time.Time `json:"createdAt"`

	// Relationships
	Conversation Conversation `json:"conversation" gorm:"foreignKey:ConversationID"`
	Message      Message      `json:"message" gorm:"foreignKey:MessageID"`
	FromAIModel  AIModel      `json:"fromAiModel" gorm:"foreignKey:FromAIModelID"`
	ToAIModel    AIModel      `json:"toAiModel" gorm:"foreignKey:ToAIModelID"`
}


// BeforeCreate is a GORM hook that validates the AI model before creation
func (a *AIModel) BeforeCreate(tx *gorm.DB) error {
	if a.Priority < 1 {
		a.Priority = 1
	}
	if a.MaxTokens < 1 {
		a.MaxTokens = 1000
	}
	if a.Temperature < 0 {
		a.Temperature = 0
	} else if a.Temperature > 2 {
		a.Temperature = 2
	}
	if a.TopP < 0 {
		a.TopP = 0
	} else if a.TopP > 1 {
		a.TopP = 1
	}
	return nil
}

// BeforeUpdate is a GORM hook that validates the AI model before update
func (a *AIModel) BeforeUpdate(tx *gorm.DB) error {
	if a.Priority < 1 {
		a.Priority = 1
	}
	if a.MaxTokens < 1 {
		a.MaxTokens = 1000
	}
	if a.Temperature < 0 {
		a.Temperature = 0
	} else if a.Temperature > 2 {
		a.Temperature = 2
	}
	if a.TopP < 0 {
		a.TopP = 0
	} else if a.TopP > 1 {
		a.TopP = 1
	}
	return nil
}

// IsActive checks if the AI model is active
func (a *AIModel) IsActive() bool {
	return a.Active
}

// IsOpenAI checks if the AI model is an OpenAI model
func (a *AIModel) IsOpenAI() bool {
	return a.Type == "openai"
}

// IsLocal checks if the AI model is a local model
func (a *AIModel) IsLocal() bool {
	return a.Type == "local"
}

// IsCustom checks if the AI model is a custom model
func (a *AIModel) IsCustom() bool {
	return a.Type == "custom"
}
