package cmd

import (
	"agent-wdd/cmd/xray"
	"agent-wdd/host_info"
	"agent-wdd/log"
	"agent-wdd/op"
	"agent-wdd/utils"
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"text/template"

	"github.com/spf13/cobra"
)

// 添加proxy子命令
func addProxySubcommands(cmd *cobra.Command) {
	xrayCmd := &cobra.Command{
		Use:   "xray",
		Short: "Xray相关操作",
	}
	xrayCmd.AddCommand(
		&cobra.Command{
			Use:   "install",
			Short: "安装Xray",
			Run: func(cmd *cobra.Command, args []string) {
				log.Info("Installing Xray...")

				installXray()
			},
		},
		&cobra.Command{
			Use:   "remove",
			Short: "移除Xray",
			Run: func(cmd *cobra.Command, args []string) {
				log.Info("Removing Xray...")

				removeXray()
			},
		},
		// 其他xray子命令...
	)

	vmessCmd := &cobra.Command{
		Use:   "vmess [port]",
		Short: "VMESS代理安装",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Setting up VMESS proxy...")

			var port string

			if len(args) == 0 {
				log.Info("no port provided, using default port 443")
				port = "443"
			} else {
				port = args[0]
			}

			// 执行info all命令 获得归一化的名字 高耦合方案 不推荐
			// for _, command := range cmd.Parent().Parent().Commands() {
			// 	if command.Name() == "info" {
			// 		command.Run(command, []string{"all"})
			// 	}
			// }

			// 2. 调用 info all 命令
			if err := executeInfoAll(cmd); err != nil {
				fmt.Printf("Error executing info all: %v\n", err)
			}

			installVmess(port)
		},
	}

	vlessCmd := &cobra.Command{
		Use:   "vless [port]",
		Short: "VLESS代理安装",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Setting up VLESS proxy...")

			// var port string

			// if len(args) == 0 {
			// 	log.Info("no port provided, using default port 443")
			// 	port = "443"
			// }
		},
	}
	cmd.AddCommand(
		xrayCmd,
		vmessCmd,
		vlessCmd,
		// 其他proxy子命令...
	)
}

// 移除Xray
func removeXray() {

}

func executeInfoAll(cmd *cobra.Command) any {
	// 获取根命令
	rootCmd := cmd.Root()

	// 创建临时上下文
	infoCmd, _, err := rootCmd.Find([]string{"info", "all"})
	if err != nil {
		return fmt.Errorf("command not found: %w", err)
	}

	// 克隆命令避免污染原始配置
	clonedCmd := cloneCommand(infoCmd)

	// 重置命令状态
	clonedCmd.SetArgs([]string{})
	clonedCmd.SilenceErrors = true
	clonedCmd.SilenceUsage = true

	// 执行命令
	return clonedCmd.Execute()
}

// 深度克隆命令的工具函数
func cloneCommand(cmd *cobra.Command) *cobra.Command {
	cloned := &cobra.Command{
		Use:     cmd.Use,
		Run:     cmd.Run,
		PreRun:  cmd.PreRun,
		PostRun: cmd.PostRun,
	}
	cloned.Flags().AddFlagSet(cmd.Flags())
	return cloned
}

// VmessConfig 定义模板数据模型
type VmessConfig struct {
	PORT string
	UUID string
}

type VmessClientConfig struct {
	ServerNodeName    string
	ServerNodeAddress string
	VmessConfig
}

// 安装VMESS代理 最简单快速的模式
func installVmess(port string) (bool, []string) {

	// 检查是否安装了xray
	if !op.CommandExistsByPath("xray") {
		log.Error("Xray is not installed, please install xray first")
		return false, []string{"Xray is not installed, please install xray first"}
	}

	// 构建配置
	// 创建新模板并解析
	tmpl, err := template.New("vmessConfig").Parse(xray.VmessServerTemplate)
	if err != nil {
		return false, []string{err.Error()}
	}

	// 准备模板数据

	// 执行 xray uuid 拿到返回值
	ok, resultLog := op.SingleLineCommandExecutor([]string{"xray", "uuid"})
	if !ok {
		return false, resultLog
	}

	if len(resultLog) == 0 {
		return false, []string{
			"xray uuid generate error ! cant not get the uuid",
		}
	}
	uuid := resultLog[0]

	vmessConfig := VmessConfig{
		PORT: port,
		UUID: uuid,
	}

	// 执行模板渲染
	var result bytes.Buffer
	if err := tmpl.Execute(&result, vmessConfig); err != nil {
		return false, []string{
			err.Error(),
		}
	}

	// 将result写入到 /usr/local/etc/xray/config.json 中
	// 直接访问底层字节切片避免拷贝
	data := result.Bytes()

	// 快速验证JSON格式
	if !json.Valid(data) {
		return false, []string{fmt.Sprintf("Invalid JSON format: %s", data)}
	}

	// 使用适当权限创建文件并写入（O_WRONLY|O_CREATE|O_TRUNC, 0644）
	filename := "/usr/local/etc/xray/config.json"
	if err := os.WriteFile(filename, data, 0644); err != nil {
		return false, []string{err.Error()}
	}

	fmt.Println("xray config file is written to ", filename)
	// 移除encode自动添加的换行，重新缩进格式化
	var prettyJSON bytes.Buffer
	if err := json.Indent(&prettyJSON, bytes.TrimSpace(data), "", "  "); err != nil {
		fmt.Printf("JSON indent error: %v\n", err)
	}

	fmt.Println(prettyJSON.String())
	fmt.Println()

	// 重启Xray
	op.SystemdRestart("xray")
	ok, resultLog = op.SystemIsRunning("xray")
	if !ok {
		log.Error("Xray service is not running => %s Maybe the config file is not valid", resultLog)
		return false, resultLog
	}

	result.Reset() // 清空全局buffer以备后续使用

	// 输出 client的配置
	configCache := host_info.ConfigCache

	// 获取服务器节点名称
	serverNodeName := configCache.Agent.OS.Hostname

	vmessClientConfig := VmessClientConfig{
		ServerNodeName:    serverNodeName,
		ServerNodeAddress: configCache.Agent.Network.Public.IPv4,
		VmessConfig:       vmessConfig,
	}

	// 执行模板渲染
	clientTmpl, err := template.New("vmessClientConfig").Parse(xray.VmessClientTemplate)
	if err != nil {
		return false, []string{err.Error()}
	}
	if err := clientTmpl.Execute(&result, vmessClientConfig); err != nil {
		return false, []string{
			err.Error(),
		}
	}

	lines := strings.Split(string(result.Bytes()), "\n")

	// for index, line := range lines {
	// 	fmt.Println(index, line)
	// }

	// 转换为字节切片并进行Base64编码
	v2rayNGConfig := "vmess://" + base64.StdEncoding.EncodeToString([]byte(lines[2]))

	// 将result 打印的终端
	fmt.Println("Clash client config is below: ")
	fmt.Println()
	fmt.Println(lines[1])
	fmt.Println()
	fmt.Println("V2rayNG config is below: ")
	fmt.Println()
	fmt.Println(v2rayNGConfig)
	fmt.Println()

	return true, []string{"Xray Configuration file written successfully"}
}

// 安装Xray 最新版本 主机可以联网才可以
func installXray() {

	installScriptUrl := "https://gitea.107421.xyz/zeaslity/Xray-install/raw/branch/main/install-release.sh"
	// 下载安装脚本
	ok, err := utils.DownloadFile(installScriptUrl, "/tmp/install-release.sh")
	if !ok {
		log.Error("Download Xray install script failed ! from %s error is %s", installScriptUrl, err)
		return
	}

	// 添加执行权限
	utils.PermissionFileExecute("/tmp/install-release.sh")

	// 执行安装脚本
	ok, resultLog := op.RealTimeCommandExecutor([]string{"/bin/bash", "/tmp/install-release.sh", "-u", "root", "install"})
	if !ok {
		log.Error("Install Xray failed ! error is %s", resultLog)
		return
	}

	op.SystemdUp("xray")
	op.SystemdEnable("xray")

	// 默认服务已经启动！ 检查
	ok, resultLog = op.SystemIsRunning("xray")
	if !ok {
		log.Error("Xray service is not running => %s", resultLog)
		return
	}

	// 安装成功
	log.Info("Xray installed successfully")

}
