package main

import (
	"bufio"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/mr-tron/base58"
	"golang.org/x/net/proxy"
)

func readLines(path string) []string {
	file, err := os.Open(path)
	if err != nil {
		return []string{}
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line != "" && !strings.HasPrefix(line, "#") {
			lines = append(lines, line)
		}
	}
	return lines
}

func isValidKey(k string) bool {
	decoded, err := base58.Decode(k)
	if err != nil {
		return false
	}
	return len(decoded) == 64
}

func loadPrivateKeys() []string {
	keys := []string{}

	// Load from private_keys.txt
	for _, key := range readLines("private_keys.txt") {
		if isValidKey(key) {
			keys = append(keys, key)
		}
	}

	// Load from keys/*.txt
	keysDir := "keys"
	if info, err := os.Stat(keysDir); err == nil && info.IsDir() {
		files, _ := filepath.Glob(filepath.Join(keysDir, "*.txt"))
		for _, file := range files {
			for _, key := range readLines(file) {
				if isValidKey(key) {
					keys = append(keys, key)
				}
			}
		}
	}

	return keys
}

func loadProxies() []string {
	return readLines("proxies.txt")
}

var proxies []string
var proxyIndex int

func initProxies() {
	proxies = loadProxies()
	proxyIndex = 0
}

func getNextProxy() (*http.Transport, error) {
	if len(proxies) == 0 {
		return &http.Transport{}, nil
	}

	proxyURL := proxies[proxyIndex]
	proxyIndex = (proxyIndex + 1) % len(proxies)

	// Parse SOCKS5 proxy
	u, err := url.Parse(proxyURL)
	if err != nil {
		return nil, fmt.Errorf("invalid proxy URL: %w", err)
	}

	if u.Scheme == "socks5" {
		var auth *proxy.Auth
		if u.User != nil {
			password, _ := u.User.Password()
			auth = &proxy.Auth{
				User:     u.User.Username(),
				Password: password,
			}
		}

		dialer, err := proxy.SOCKS5("tcp", u.Host, auth, proxy.Direct)
		if err != nil {
			return nil, fmt.Errorf("failed to create SOCKS5 dialer: %w", err)
		}

		return &http.Transport{
			Dial: dialer.Dial,
		}, nil
	}

	// For HTTP/HTTPS proxies
	return &http.Transport{
		Proxy: http.ProxyURL(u),
	}, nil
}
