package cmd

import (
	"agent-wdd/log"
	"agent-wdd/utils"
	"context"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"

	"github.com/spf13/cobra"
	"golang.org/x/net/proxy"
)

// 示例：添加download子命令
func addDownloadSubcommands(cmd *cobra.Command) {
	proxyCmd := &cobra.Command{
		Use:   "proxy [proxyUrl] [url] [dest]",
		Short: "使用代理下载 socks5://[username]:[password]@ip:port http://[username]:[password]@ip:port",
		Args:  cobra.ExactArgs(3),
		Run: func(cmd *cobra.Command, args []string) {
			proxyURL := args[0]
			fileURL := args[1]
			destPath := args[2]

			log.Info("Downloading using proxy: %s -> from %s to %s\n", proxyURL, fileURL, destPath)

			// 创建带代理的HTTP客户端
			client, err := createProxyClient(proxyURL)
			if err != nil {
				log.Error("创建代理客户端失败: %v", err)
			}

			// 执行下载
			downloadOk, resultLog := utils.DownloadFileWithClient(client, fileURL, destPath)
			if !downloadOk {
				log.Error("下载失败: %v", resultLog)
			} else {
				log.Info("文件下载完成")
			}

		},
	}

	cmd.Run = func(cmd *cobra.Command, args []string) {

		if len(args) == 0 {
			log.Error("请输入下载地址")
			return
		} else if len(args) == 1 {
			timeString := utils.CurrentTimeString()
			args = append(args, "./"+timeString+".txt")
		}

		log.Info("Downloading without proxy: %s -> %s\n", args[0], args[1])

		downloadOk, resultLog := utils.DownloadFile(args[0], args[1])
		if !downloadOk {
			log.Error("下载失败: %s", resultLog)
		} else {
			log.Info("下载成功: %s", args[1])
		}

	}

	cmd.AddCommand(proxyCmd)
}

// 创建带代理的HTTP客户端
func createProxyClient(proxyURL string) (*http.Client, error) {
	parsedURL, err := url.Parse(proxyURL)
	if err != nil {
		return nil, fmt.Errorf("无效的代理URL: %w", err)
	}

	switch parsedURL.Scheme {
	case "socks5":
		return createSocks5Client(parsedURL)
	case "http", "https":
		return createHTTPClient(parsedURL), nil
	default:
		return nil, fmt.Errorf("不支持的代理协议: %s", parsedURL.Scheme)
	}
}

// 创建SOCKS5代理客户端
func createSocks5Client(proxyURL *url.URL) (*http.Client, error) {
	var auth *proxy.Auth
	if proxyURL.User != nil {
		password, _ := proxyURL.User.Password()
		auth = &proxy.Auth{
			User:     proxyURL.User.Username(),
			Password: password,
		}
	}

	dialer, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, proxy.Direct)
	if err != nil {
		return nil, fmt.Errorf("创建SOCKS5拨号器失败: %w", err)
	}

	return &http.Client{
		Transport: &http.Transport{
			DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
				return dialer.Dial(network, addr)
			},
		},
		Timeout: 10 * time.Second,
	}, nil
}

// 创建HTTP代理客户端
func createHTTPClient(proxyURL *url.URL) *http.Client {
	return &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyURL(proxyURL),
		},
		Timeout: 30 * time.Minute,
	}
}
