package config

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

type Config struct {
	CouchDb     CouchDbConfig `json:"couchDb"`
	MailSources []MailSource  `json:"mailSources"`
}

type CouchDbConfig struct {
	URL      string `json:"url"`
	User     string `json:"user"`
	Password string `json:"password"`
	Database string `json:"database"`
}

type MailSource struct {
	Name          string        `json:"name"`
	Enabled       bool          `json:"enabled"`
	Protocol      string        `json:"protocol"`
	Host          string        `json:"host"`
	Port          int           `json:"port"`
	User          string        `json:"user"`
	Password      string        `json:"password"`
	Sync          bool          `json:"sync"`
	FolderFilter  FolderFilter  `json:"folderFilter"`
	MessageFilter MessageFilter `json:"messageFilter"`
}

type FolderFilter struct {
	Include []string `json:"include"`
	Exclude []string `json:"exclude"`
}

type MessageFilter struct {
	Since string `json:"since,omitempty"`
}

func LoadConfig(path string) (*Config, error) {
	configFile, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer configFile.Close()

	var config Config
	jsonParser := json.NewDecoder(configFile)
	if err = jsonParser.Decode(&config); err != nil {
		return nil, err
	}

	return &config, nil
}

// FindConfigFile searches for config.json in the following order:
// 1. Path specified by -config flag
// 2. ./config.json (current directory)
// 3. ~/.config/mail2couch/config.json (user config directory)
// 4. ~/.mail2couch.json (user home directory)
func FindConfigFile() (string, error) {
	// Check for command line flag
	configFlag := flag.String("config", "", "Path to configuration file")
	flag.Parse()

	if *configFlag != "" {
		if _, err := os.Stat(*configFlag); err == nil {
			return *configFlag, nil
		}
		return "", fmt.Errorf("specified config file not found: %s", *configFlag)
	}

	// List of possible config file locations in order of preference
	candidates := []string{
		"config.json",        // Current directory
		"config/config.json", // Config subdirectory
	}

	// Add user directory paths
	if homeDir, err := os.UserHomeDir(); err == nil {
		candidates = append(candidates,
			filepath.Join(homeDir, ".config", "mail2couch", "config.json"),
			filepath.Join(homeDir, ".mail2couch.json"),
		)
	}

	// Try each candidate location
	for _, candidate := range candidates {
		if _, err := os.Stat(candidate); err == nil {
			return candidate, nil
		}
	}

	return "", fmt.Errorf("no configuration file found. Searched locations: %v", candidates)
}

// LoadConfigWithDiscovery loads configuration using automatic file discovery
func LoadConfigWithDiscovery() (*Config, error) {
	configPath, err := FindConfigFile()
	if err != nil {
		return nil, err
	}

	fmt.Printf("Using configuration file: %s\n", configPath)
	return LoadConfig(configPath)
}
