package config

import (
	"fmt"
	"os"
	"path/filepath"

	"gopkg.in/yaml.v3"
)

// Config represents the application configuration.
// All settings live in a single config.yaml — no separate .env file.
type Config struct {
	Server   ServerConfig   `yaml:"server"`
	Database DatabaseConfig `yaml:"database"`
	SMTP     SMTPSettings   `yaml:"smtp"`
	IMAP     IMAPConfig     `yaml:"imap_defaults"`
	AI       AIConfig       `yaml:"ai"`
	Worker   WorkerConfig   `yaml:"worker"`
	Folders  FolderConfig   `yaml:"folders"`
	Logging  LoggingConfig  `yaml:"logging"`
}

// ServerConfig holds web server configuration
type ServerConfig struct {
	Port          int    `yaml:"port"`
	Host          string `yaml:"host"`
	SessionSecret string `yaml:"session_secret"`
}

// DatabaseConfig holds database configuration
type DatabaseConfig struct {
	Path        string `yaml:"path"`
	AutoMigrate bool   `yaml:"auto_migrate"`
}

// SMTPSettings holds SMTP credentials for sending OTP emails.
// Previously stored in a separate .env file; now in config.yaml.
type SMTPSettings struct {
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
}

// IMAPConfig holds default IMAP configuration
type IMAPConfig struct {
	Host                string `yaml:"host"`
	Port                int    `yaml:"port"`
	TLS                 bool   `yaml:"tls"`
	BatchSize           int    `yaml:"batch_size"`
	PollIntervalMinutes int    `yaml:"poll_interval_minutes"`
}

// AIConfig holds AI classification configuration.
// api_key was previously in .env; now stored here.
type AIConfig struct {
	Model       string  `yaml:"model"`
	MaxTokens   int     `yaml:"max_tokens"`
	Temperature float64 `yaml:"temperature"`
	PromptFile  string  `yaml:"prompt_file"`
	APIKey      string  `yaml:"api_key"`
}

// WorkerConfig holds background worker configuration
type WorkerConfig struct {
	SteadyStateBatchSize       int `yaml:"steady_state_batch_size"`
	SteadyStateIntervalMinutes  int `yaml:"steady_state_interval_minutes"`
	CatchUpBatchSize           int `yaml:"catch_up_batch_size"`
	CatchUpCooldownSeconds     int `yaml:"catch_up_cooldown_seconds"`
}

// FolderConfig holds email folder names
type FolderConfig struct {
	Important     string `yaml:"important"`
	Ecommerce     string `yaml:"ecommerce"`
	Notifications string `yaml:"notifications"`
	Finance       string `yaml:"finance"`
	Social        string `yaml:"social"`
	Other         string `yaml:"other"`
	Spam          string `yaml:"spam"`
}

// LoggingConfig holds logging configuration
type LoggingConfig struct {
	Level      string `yaml:"level"`
	File       string `yaml:"file"`
	MaxSizeMB  int    `yaml:"max_size_mb"`
	MaxBackups int    `yaml:"max_backups"`
	MaxAgeDays int    `yaml:"max_age_days"`
}

// LoadConfig loads configuration from a YAML file.
// No .env file is consulted — everything is in config.yaml.
func LoadConfig(configPath string) (*Config, error) {
	data, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("failed to read config file: %w", err)
	}

	var config Config
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("failed to parse config file: %w", err)
	}

	return &config, nil
}

// GetDefaultConfigPath returns the default path to config.yaml.
// It looks for config.yaml in the same directory as the executable.
func GetDefaultConfigPath() (string, error) {
	execPath, err := os.Executable()
	if err != nil {
		return "bin/config.yaml", nil
	}

	execDir := filepath.Dir(execPath)
	return filepath.Join(execDir, "config.yaml"), nil
}