package config

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

var (
	ConfigDir         string
	SubscriptionsFile string
	ConfigsFile       string
	StateFile         string
	SettingsFile      string
	LogsDir           string
	XrayDir           string
	V2RayDir          string
)

type WireGuardConfig struct {
	Name   string `json:"name"`
	Config string `json:"config"`
}

type VLESSConfig struct {
	Name         string `json:"name"`
	URL          string `json:"url"`
	Protocol     string `json:"protocol,omitempty"`
	Subscription string `json:"subscription,omitempty"`
}

type Configs struct {
	WireGuard []WireGuardConfig `json:"wireguard"`
	VLESS     []VLESSConfig     `json:"vless"`
}

type Subscription struct {
	Name string `json:"name"`
	URL  string `json:"url"`
}

type Subscriptions struct {
	Subscriptions []Subscription `json:"subscriptions"`
}

type ConnectionState struct {
	Connected  bool   `json:"connected"`
	ConfigName string `json:"config_name"`
	ConfigType string `json:"config_type"`
	StartTime  string `json:"start_time"`
	Interface  string `json:"interface"`
	ProcessPID int    `json:"process_pid"`
	LogFile    string `json:"log_file"`
}

type Settings struct {
	CoreType string `json:"core_type"` // "xray" или "v2ray"
}

// Init инициализирует конфигурационные директории и файлы
func Init() error {
	// Получаем рабочую директорию
	workDir, err := os.Getwd()
	if err != nil {
		return err
	}

	ConfigDir = filepath.Join(workDir, ".vpn_client")
	SubscriptionsFile = filepath.Join(ConfigDir, "subscriptions.json")
	ConfigsFile = filepath.Join(ConfigDir, "configs.json")
	StateFile = filepath.Join(ConfigDir, "state.json")
	SettingsFile = filepath.Join(ConfigDir, "settings.json")
	LogsDir = filepath.Join(workDir, "logs")
	XrayDir = filepath.Join(workDir, "xray")
	V2RayDir = filepath.Join(workDir, "v2ray")

	// Создаем директории
	if err := os.MkdirAll(ConfigDir, 0755); err != nil {
		return err
	}
	if err := os.MkdirAll(LogsDir, 0755); err != nil {
		return err
	}

	// Инициализируем файлы если их нет
	if err := initFileIfNotExists(SubscriptionsFile, Subscriptions{Subscriptions: []Subscription{}}); err != nil {
		return err
	}
	if err := initFileIfNotExists(ConfigsFile, Configs{WireGuard: []WireGuardConfig{}, VLESS: []VLESSConfig{}}); err != nil {
		return err
	}
	if err := initFileIfNotExists(StateFile, ConnectionState{}); err != nil {
		return err
	}
	if err := initFileIfNotExists(SettingsFile, Settings{CoreType: "xray"}); err != nil {
		return err
	}

	return nil
}

func initFileIfNotExists(path string, defaultData interface{}) error {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		data, err := json.MarshalIndent(defaultData, "", "  ")
		if err != nil {
			return err
		}
		return os.WriteFile(path, data, 0644)
	}
	return nil
}

// LoadConfigs загружает конфигурации
func LoadConfigs() (*Configs, error) {
	data, err := os.ReadFile(ConfigsFile)
	if err != nil {
		return nil, err
	}

	var configs Configs
	if err := json.Unmarshal(data, &configs); err != nil {
		return nil, err
	}

	return &configs, nil
}

// SaveConfigs сохраняет конфигурации
func SaveConfigs(configs *Configs) error {
	data, err := json.MarshalIndent(configs, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(ConfigsFile, data, 0644)
}

// LoadSubscriptions загружает подписки
func LoadSubscriptions() (*Subscriptions, error) {
	data, err := os.ReadFile(SubscriptionsFile)
	if err != nil {
		return nil, err
	}

	var subs Subscriptions
	if err := json.Unmarshal(data, &subs); err != nil {
		return nil, err
	}

	return &subs, nil
}

// SaveSubscriptions сохраняет подписки
func SaveSubscriptions(subs *Subscriptions) error {
	data, err := json.MarshalIndent(subs, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(SubscriptionsFile, data, 0644)
}

// LoadState загружает состояние подключения
func LoadState() (*ConnectionState, error) {
	data, err := os.ReadFile(StateFile)
	if err != nil {
		return nil, err
	}

	var state ConnectionState
	if err := json.Unmarshal(data, &state); err != nil {
		return nil, err
	}

	return &state, nil
}

// SaveState сохраняет состояние подключения
func SaveState(state *ConnectionState) error {
	data, err := json.MarshalIndent(state, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(StateFile, data, 0644)
}

// LoadSettings загружает настройки
func LoadSettings() (*Settings, error) {
	data, err := os.ReadFile(SettingsFile)
	if err != nil {
		return nil, err
	}

	var settings Settings
	if err := json.Unmarshal(data, &settings); err != nil {
		return nil, err
	}

	// По умолчанию xray
	if settings.CoreType == "" {
		settings.CoreType = "xray"
	}

	return &settings, nil
}

// SaveSettings сохраняет настройки
func SaveSettings(settings *Settings) error {
	data, err := json.MarshalIndent(settings, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(SettingsFile, data, 0644)
}
