package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"time"

	"gopkg.in/ini.v1"
)

func initConfig() error {
	if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
		return createConfig()
	}

	printInfo("Configuration file already exists.")
	config = loadConfig()
	return nil
}

func createConfig() error {
	reader := bufio.NewReader(os.Stdin)

	printMessage("Configuration file not found.")
	printMessage("Do you want to use default values? (yes/no): ")
	useDefaults, _ := reader.ReadString('\n')

	if strings.TrimSpace(useDefaults) != "yes" {
		printMessage("Enter port (default 5000): ")
		portStr, _ := reader.ReadString('\n')
		if portStr != "\n" {
			port, err := strconv.Atoi(strings.TrimSpace(portStr))
			if err != nil {
				config.Port = 5000
			} else {
				config.Port = port
			}
		}

		printMessage("Enter your domain address (default localhost): ")
		domain, _ := reader.ReadString('\n')
		if domain != "\n" {
			config.Domain = strings.TrimSpace(domain)
		}
	} else {
		config = defaultConfig
	}

	if config.AuthCode == "" {
		config.AuthCode = generateStrongRandomString(64)
		printMessage("Generated connection code: %s\n", config.AuthCode)
	}

	config.NodesEnabled = len(config.Peers) > 0
	config.CrawlerEnabled = true
	config.WebsiteEnabled = true
	config.LogLevel = 1

	saveConfig(config)
	return nil
}

func saveConfig(config Config) {
	cfg := ini.Empty()
	sec := cfg.Section("")
	sec.Key("Port").SetValue(strconv.Itoa(config.Port))
	sec.Key("AuthCode").SetValue(config.AuthCode)
	sec.Key("PeerID").SetValue(config.PeerID)

	peers := strings.Join(config.Peers, ",")
	sec.Key("Peers").SetValue(peers)
	sec.Key("Domain").SetValue(config.Domain)
	sec.Key("NodesEnabled").SetValue(strconv.FormatBool(config.NodesEnabled))
	sec.Key("CrawlerEnabled").SetValue(strconv.FormatBool(config.CrawlerEnabled))
	sec.Key("WebsiteEnabled").SetValue(strconv.FormatBool(config.WebsiteEnabled))
	sec.Key("LogLevel").SetValue(strconv.Itoa(config.LogLevel))
	sec.Key("HardCacheDuration").SetValue(config.HardCacheDuration.String())

	err := cfg.SaveTo(configFilePath)
	if err != nil {
		printErr("Error writing to config file: %v", err)
	}
}

func loadConfig() Config {
	cfg, err := ini.Load(configFilePath)
	if err != nil {
		printErr("Error opening config file: %v", err)
	}

	port, err := cfg.Section("").Key("Port").Int()
	if err != nil || port == 0 {
		port = 5000 // Default to 5000 if not set or error
	}

	peersStr := cfg.Section("").Key("Peers").String()
	var peers []string
	if peersStr != "" {
		peers = strings.Split(peersStr, ",")
		for i, peer := range peers {
			peers[i] = addProtocol(peer)
		}
	}

	domain := cfg.Section("").Key("Domain").String()
	if domain == "" {
		domain = "localhost" // Default to localhost if not set
	}

	nodesEnabled, err := cfg.Section("").Key("NodesEnabled").Bool()
	if err != nil { // If NodesEnabled is not found in config
		nodesEnabled = len(peers) > 0 // Enable nodes if peers are configured
	}

	crawlerEnabled, err := cfg.Section("").Key("CrawlerEnabled").Bool()
	if err != nil { // Default to true if not found
		crawlerEnabled = true
	}

	websiteEnabled, err := cfg.Section("").Key("WebsiteEnabled").Bool()
	if err != nil { // Default to true if not found
		websiteEnabled = true
	}

	logLevel, err := cfg.Section("").Key("LogLevel").Int()
	if err != nil || logLevel < 0 || logLevel > 4 { // Default to 1 if not found or out of range
		logLevel = 1
	}

	// Read HardCacheDuration
	hardCacheStr := cfg.Section("").Key("HardCacheDuration").String()
	var hardCacheDuration time.Duration
	if hardCacheStr != "" {
		duration, err := time.ParseDuration(hardCacheStr)
		if err != nil {
			printWarn("Invalid HardCacheDuration format, defaulting to 0: %v", err)
			hardCacheDuration = 0
		} else {
			hardCacheDuration = duration
		}
	} else {
		hardCacheDuration = 0 // Default to 0 if not set
	}

	config = Config{
		Port:              port,
		AuthCode:          cfg.Section("").Key("AuthCode").String(),
		PeerID:            cfg.Section("").Key("PeerID").String(),
		Peers:             peers,
		Domain:            domain,
		NodesEnabled:      nodesEnabled,
		CrawlerEnabled:    crawlerEnabled,
		WebsiteEnabled:    websiteEnabled,
		LogLevel:          logLevel,
		HardCacheDuration: hardCacheDuration,
		HardCacheEnabled:  hardCacheDuration != 0,
	}

	return config
}