package config

import (
	"os"
	"paraclub-ai-mailer/internal/logger"
	"strings"
	"time"

	"github.com/sirupsen/logrus"
	"gopkg.in/yaml.v3"
)

type Config struct {
	IMAP    IMAPConfig    `yaml:"imap"`
	AI      AIConfig      `yaml:"ai"`
	Context ContextConfig `yaml:"context"`
	Polling PollingConfig `yaml:"polling"`
	Logging LoggingConfig `yaml:"logging"`
}

type IMAPConfig struct {
	Server       string `yaml:"server"`
	Port         int    `yaml:"port"`
	Username     string `yaml:"username"`
	Password     string `yaml:"password"`
	MailboxIn    string `yaml:"mailbox_in"`
	DraftBox     string `yaml:"draft_box"`
	ProcessedBox string `yaml:"processed_box"`
	UseTLS       bool   `yaml:"use_tls"`
}

type AIConfig struct {
	OpenRouterAPIKey string  `yaml:"openrouter_api_key"`
	Model            string  `yaml:"model"`
	Temperature      float32 `yaml:"temperature"`
	MaxTokens        int     `yaml:"max_tokens"`
}

type ContextConfig struct {
	URLs []string `yaml:"urls"`
}

type PollingConfig struct {
	Interval time.Duration `yaml:"interval"`
}

type LoggingConfig struct {
	Level    string `yaml:"level"`
	FilePath string `yaml:"file_path"`
}

func readFileContent(path string) (string, error) {
	content, err := os.ReadFile(path)
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(content)), nil
}

func Load(path string) (*Config, error) {
	logger.WithField("path", path).Debug("Loading configuration file")

	data, err := os.ReadFile(path)
	if err != nil {
		logger.WithError(err).Error("Failed to read configuration file")
		return nil, err
	}
	logger.WithField("bytes", len(data)).Debug("Read configuration file")

	var config Config
	if err := yaml.Unmarshal(data, &config); err != nil {
		logger.WithError(err).Error("Failed to parse YAML configuration")
		return nil, err
	}

	// Handle IMAP password from environment or file
	if strings.HasPrefix(config.IMAP.Password, "${") && strings.HasSuffix(config.IMAP.Password, "}") {
		envVar := strings.TrimSuffix(strings.TrimPrefix(config.IMAP.Password, "${"), "}")
		config.IMAP.Password = os.Getenv(envVar)
		logger.WithField("envVar", envVar).Debug("Resolved IMAP password from environment")
	} else if strings.HasPrefix(config.IMAP.Password, "file://") {
		filePath := strings.TrimPrefix(config.IMAP.Password, "file://")
		password, err := readFileContent(filePath)
		if err != nil {
			logger.WithError(err).Error("Failed to read IMAP password from file")
			return nil, err
		}
		config.IMAP.Password = password
		logger.WithField("path", filePath).Debug("Read IMAP password from file")
	}

	// Handle OpenRouter API key from environment or file
	if strings.HasPrefix(config.AI.OpenRouterAPIKey, "${") && strings.HasSuffix(config.AI.OpenRouterAPIKey, "}") {
		envVar := strings.TrimSuffix(strings.TrimPrefix(config.AI.OpenRouterAPIKey, "${"), "}")
		config.AI.OpenRouterAPIKey = os.Getenv(envVar)
		logger.WithField("envVar", envVar).Debug("Resolved OpenRouter API key from environment")
	} else if strings.HasPrefix(config.AI.OpenRouterAPIKey, "file://") {
		filePath := strings.TrimPrefix(config.AI.OpenRouterAPIKey, "file://")
		apiKey, err := readFileContent(filePath)
		if err != nil {
			logger.WithError(err).Error("Failed to read OpenRouter API key from file")
			return nil, err
		}
		config.AI.OpenRouterAPIKey = apiKey
		logger.WithField("path", filePath).Debug("Read OpenRouter API key from file")
	}

	logger.WithFields(logrus.Fields{
		"imapServer":      config.IMAP.Server,
		"imapPort":        config.IMAP.Port,
		"imapUsername":    config.IMAP.Username,
		"imapMailboxIn":   config.IMAP.MailboxIn,
		"imapDraftBox":    config.IMAP.DraftBox,
		"imapUseTLS":      config.IMAP.UseTLS,
		"aiModel":         config.AI.Model,
		"aiTemperature":   config.AI.Temperature,
		"aiMaxTokens":     config.AI.MaxTokens,
		"contextUrlCount": len(config.Context.URLs),
		"pollingInterval": config.Polling.Interval,
		"loggingLevel":    config.Logging.Level,
		"loggingFilePath": config.Logging.FilePath,
	}).Debug("Configuration loaded successfully")

	return &config, nil
}
