package subscription

import (
	"encoding/base64"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"

	"vpn-client/internal/config"
	"vpn-client/internal/logger"
)

// FetchConfigs загружает конфигурации из подписки
func FetchConfigs(subscriptionURL, logsDir string) ([]config.VLESSConfig, error) {
	logFile := logger.GetLogPath(logsDir, "subscription")
	logger.LogMessage(logFile, fmt.Sprintf("Начало загрузки подписки: %s", subscriptionURL))

	// Создаем HTTP клиент с таймаутом
	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	resp, err := client.Get(subscriptionURL)
	if err != nil {
		logger.LogMessage(logFile, fmt.Sprintf("Ошибка загрузки подписки: %v", err))
		return nil, fmt.Errorf("ошибка загрузки подписки: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("ошибка HTTP: %d", resp.StatusCode)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("ошибка чтения ответа: %w", err)
	}

	// Пытаемся декодировать base64
	content := string(body)
	if decoded, err := base64.StdEncoding.DecodeString(content); err == nil {
		content = string(decoded)
	}

	// Парсим конфигурации
	var configs []config.VLESSConfig
	lines := strings.Split(content, "\n")

	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}

		var protocol string
		var name string
		var configURL string

		// VLESS конфиги
		if strings.HasPrefix(line, "vless://") {
			protocol = "VLESS"
			configURL = line
			if parsed, err := url.Parse(line); err == nil && parsed.Fragment != "" {
				name, _ = url.QueryUnescape(parsed.Fragment)
			} else {
				name = fmt.Sprintf("VLESS_%d", len(configs)+1)
			}
			configs = append(configs, config.VLESSConfig{
				Name:     name,
				URL:      configURL,
				Protocol: protocol,
			})
		} else if strings.HasPrefix(line, "vmess://") {
			protocol = "VMess"
			configURL = line
			if parsed, err := url.Parse(line); err == nil && parsed.Fragment != "" {
				name, _ = url.QueryUnescape(parsed.Fragment)
			} else {
				name = fmt.Sprintf("VMess_%d", len(configs)+1)
			}
			configs = append(configs, config.VLESSConfig{
				Name:     name,
				URL:      configURL,
				Protocol: protocol,
			})
		} else if strings.HasPrefix(line, "trojan://") {
			protocol = "Trojan"
			configURL = line
			if parsed, err := url.Parse(line); err == nil && parsed.Fragment != "" {
				name, _ = url.QueryUnescape(parsed.Fragment)
			} else {
				name = fmt.Sprintf("Trojan_%d", len(configs)+1)
			}
			configs = append(configs, config.VLESSConfig{
				Name:     name,
				URL:      configURL,
				Protocol: protocol,
			})
		} else if strings.HasPrefix(line, "ss://") {
			protocol = "Shadowsocks"
			configURL = line
			if parsed, err := url.Parse(line); err == nil && parsed.Fragment != "" {
				name, _ = url.QueryUnescape(parsed.Fragment)
			} else {
				name = fmt.Sprintf("SS_%d", len(configs)+1)
			}
			configs = append(configs, config.VLESSConfig{
				Name:     name,
				URL:      configURL,
				Protocol: protocol,
			})
		}
	}

	logger.LogMessage(logFile, fmt.Sprintf("Успешно загружено %d конфигов", len(configs)))
	return configs, nil
}

// UpdateSubscription обновляет конфигурации из подписки
func UpdateSubscription(subscriptionName, logsDir string) error {
	// Загружаем подписки
	subs, err := config.LoadSubscriptions()
	if err != nil {
		return fmt.Errorf("ошибка загрузки подписок: %w", err)
	}

	// Ищем подписку
	var sub *config.Subscription
	for i := range subs.Subscriptions {
		if subs.Subscriptions[i].Name == subscriptionName {
			sub = &subs.Subscriptions[i]
			break
		}
	}

	if sub == nil {
		return fmt.Errorf("подписка '%s' не найдена", subscriptionName)
	}

	fmt.Printf("Загрузка конфигов из '%s'...\n", subscriptionName)

	// Загружаем конфиги
	newConfigs, err := FetchConfigs(sub.URL, logsDir)
	if err != nil {
		return fmt.Errorf("ошибка загрузки конфигов: %w", err)
	}

	if len(newConfigs) == 0 {
		return fmt.Errorf("не удалось загрузить конфиги")
	}

	// Загружаем текущие конфигурации
	allConfigs, err := config.LoadConfigs()
	if err != nil {
		return fmt.Errorf("ошибка загрузки конфигураций: %w", err)
	}

	// Удаляем старые конфиги из этой подписки
	var filteredConfigs []config.VLESSConfig
	for _, cfg := range allConfigs.VLESS {
		if cfg.Subscription != subscriptionName {
			filteredConfigs = append(filteredConfigs, cfg)
		}
	}
	allConfigs.VLESS = filteredConfigs

	// Добавляем новые конфиги с префиксом подписки
	for _, cfg := range newConfigs {
		cfg.Name = fmt.Sprintf("[%s] %s", subscriptionName, cfg.Name)
		cfg.Subscription = subscriptionName
		allConfigs.VLESS = append(allConfigs.VLESS, cfg)
	}

	// Сохраняем
	if err := config.SaveConfigs(allConfigs); err != nil {
		return fmt.Errorf("ошибка сохранения конфигураций: %w", err)
	}

	fmt.Printf("✓ Обновлено %d конфигов из подписки\n", len(newConfigs))
	return nil
}
