package ollama

import (
	"context"
)

// OllamaService defines the interface for Ollama operations
type OllamaService interface {
	// Generate generates text using a specified model and prompt
	Generate(ctx context.Context, req *GenerateRequest) (*GenerateResponse, error)

	// GenerateWithOptions generates text with additional options
	GenerateWithOptions(ctx context.Context, req *GenerateRequest, opts *GenerateOptions) (*GenerateResponse, error)

	// Chat performs a conversational chat with the model
	Chat(ctx context.Context, req *ChatRequest) (*ChatResponse, error)

	// Embed generates embeddings for the given text
	Embed(ctx context.Context, req *EmbedRequest) (*EmbedResponse, error)

	// PullModel pulls a model from the registry
	PullModel(ctx context.Context, model string) (*PullResponse, error)

	// ListModels lists available models
	ListModels(ctx context.Context) (*ListModelsResponse, error)

	// DeleteModel deletes a model
	DeleteModel(ctx context.Context, model string) (*DeleteResponse, error)

	// ShowModel shows model information
	ShowModel(ctx context.Context, model string) (*ShowModelResponse, error)

	// Health checks if the Ollama service is available
	Health(ctx context.Context) error

	// NewChatBuilder creates a new chat builder for conversational interactions
	NewChatBuilder() ChatBuilder
}

// HTTPClient defines the interface for HTTP operations
type HTTPClient interface {
	// Post performs a POST request
	Post(ctx context.Context, url string, body interface{}, result interface{}) error

	// Get performs a GET request
	Get(ctx context.Context, url string, result interface{}) error

	// Delete performs a DELETE request
	Delete(ctx context.Context, url string, result interface{}) error
}

// Logger defines the interface for logging operations
type Logger interface {
	Debug(msg string, fields map[string]interface{})
	Info(msg string, fields map[string]interface{})
	Warn(msg string, fields map[string]interface{})
	Error(msg string, fields map[string]interface{})
	Fatal(msg string, fields map[string]interface{})
	WithFields(fields map[string]interface{}) Logger
	Sync() error
}

// ChatBuilder provides a fluent interface for building chat requests
type ChatBuilder interface {
	// SetModel sets the model to use
	SetModel(model string) ChatBuilder

	// SetSystem sets the system prompt
	SetSystem(system string) ChatBuilder

	// AddMessage adds a message to the conversation
	AddMessage(role MessageRole, content string) ChatBuilder

	// SetTemperature sets the temperature for generation
	SetTemperature(temperature float64) ChatBuilder

	// SetTopP sets the top_p parameter
	SetTopP(topP float64) ChatBuilder

	// SetMaxTokens sets the maximum number of tokens to generate
	SetMaxTokens(maxTokens int) ChatBuilder

	// SetStream sets whether to stream the response
	SetStream(stream bool) ChatBuilder

	// SetFormat sets the response format
	SetFormat(format string) ChatBuilder

	// SetOptions sets custom options
	SetOptions(options map[string]interface{}) ChatBuilder

	// Build creates the chat request
	Build() (*ChatRequest, error)

	// Send builds and sends the chat request
	Send(ctx context.Context) (*ChatResponse, error)

	// Continue continues the conversation with the current context
	Continue(ctx context.Context, userMessage string) (*ChatResponse, error)
}

// MessageRole represents the role of a message in a chat
type MessageRole string

const (
	MessageRoleSystem    MessageRole = "system"
	MessageRoleUser      MessageRole = "user"
	MessageRoleAssistant MessageRole = "assistant"
)

// GenerateOptions represents additional options for text generation
type GenerateOptions struct {
	Temperature   *float64               `json:"temperature,omitempty"`
	TopP          *float64               `json:"top_p,omitempty"`
	TopK          *int                   `json:"top_k,omitempty"`
	RepeatPenalty *float64               `json:"repeat_penalty,omitempty"`
	Seed          *int                   `json:"seed,omitempty"`
	Stop          []string               `json:"stop,omitempty"`
	Format        string                 `json:"format,omitempty"`
	Options       map[string]interface{} `json:"options,omitempty"`
}
