package cmd

import (
	"agent-wdd/cert_manager_wdd"
	"agent-wdd/log"
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/spf13/cobra"
)

const (
	// 证书管理命令选项
	cfAPIToken  = "T7LxBemfe8SNGWkT9uz2XIc1e22ifAbBv_POJvDP"
	certDir     = "/root/wdd/cert_manager_wdd/"
	emailAddr   = "wdd@gmail.com"
	caServer    = "zerossl"
	daysRenewal = 30
)

// 初始化证书管理配置
func initCertManagerConfig() *cert_manager_wdd.CertManager {

	// 创建证书管理器
	certManager := cert_manager_wdd.NewCertManager(certDir, cfAPIToken, emailAddr)

	// 设置证书更新阈值天数
	if daysRenewal > 0 {
		certManager.DaysBeforeRenewal = daysRenewal
	}

	// 设置CA服务器
	if caServer != "" {
		switch strings.ToLower(caServer) {
		case "letsencrypt":
			certManager.SetCAServer(cert_manager_wdd.LetsEncryptCA)
		case "zerossl":
			certManager.SetCAServer(cert_manager_wdd.ZeroSSLCA)
		default:
			log.Warning("未知的CA服务器: %s，使用默认值", caServer)
		}
	}

	return certManager
}

// 添加证书管理命令
func addCertManagerSubcommands(cmd *cobra.Command) {

	// 申请证书命令
	applyCmd := &cobra.Command{
		Use:   "apply [域名]",
		Short: "申请SSL证书",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("开始为域名 %s 申请证书", domain)

			certManager := initCertManagerConfig()
			certInfo, err := certManager.ApplyCertificate(domain)
			if err != nil {
				log.Error("证书申请失败: %v", err)
				os.Exit(1)
			}

			printCertificateInfo(certInfo)
			log.Info("证书申请成功")
		},
	}

	// 列出证书命令
	listCmd := &cobra.Command{
		Use:   "list",
		Short: "列出所有证书",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("列出所有证书")

			certManager := initCertManagerConfig()
			certs, err := certManager.GetAllCerts()
			if err != nil {
				log.Error("获取证书列表失败: %v", err)
				os.Exit(1)
			}

			if len(certs) == 0 {
				log.Info("未找到任何证书")
				return
			}

			printCertificatesList(certs)
		},
	}

	// 查看证书命令
	showCmd := &cobra.Command{
		Use:   "show [域名]",
		Short: "查看指定证书的详细信息",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("查看域名 %s 的证书信息", domain)

			certManager := initCertManagerConfig()
			certs, err := certManager.GetAllCerts()
			if err != nil {
				log.Error("获取证书列表失败: %v", err)
				os.Exit(1)
			}

			var targetCert *cert_manager_wdd.CertInfo
			for _, cert := range certs {
				if cert.Domain == domain {
					targetCert = &cert
					break
				}
			}

			if targetCert == nil {
				log.Error("未找到域名 %s 的证书", domain)
				os.Exit(1)
			}

			printCertificateDetailInfo(targetCert)
		},
	}

	// 更新证书命令
	renewCmd := &cobra.Command{
		Use:   "renew [域名]",
		Short: "更新指定证书",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("更新域名 %s 的证书", domain)

			certManager := initCertManagerConfig()
			certInfo, err := certManager.RenewCertificate(domain)
			if err != nil {
				log.Error("证书更新失败: %v", err)
				os.Exit(1)
			}

			printCertificateInfo(certInfo)
			log.Info("证书更新成功")
		},
	}

	// 更新所有需要更新的证书
	renewAllCmd := &cobra.Command{
		Use:   "renew-all",
		Short: "更新所有需要更新的证书",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("更新所有需要更新的证书")

			certManager := initCertManagerConfig()
			certs, err := certManager.GetAllCerts()
			if err != nil {
				log.Error("获取证书列表失败: %v", err)
				os.Exit(1)
			}

			needRenewalCount := 0
			for _, cert := range certs {
				if cert.NeedsRenewal {
					needRenewalCount++
					log.Info("证书 %s 需要更新 (剩余 %d 天)", cert.Domain, cert.DaysRemaining)
					certInfo, err := certManager.RenewCertificate(cert.Domain)
					if err != nil {
						log.Error("更新证书 %s 失败: %v", cert.Domain, err)
						continue
					}
					log.Info("证书 %s 更新成功", certInfo.Domain)
				}
			}

			if needRenewalCount == 0 {
				log.Info("没有需要更新的证书")
			} else {
				log.Info("共更新 %d 个证书", needRenewalCount)
			}
		},
	}

	// 将所有子命令添加到主命令
	cmd.AddCommand(applyCmd, listCmd, showCmd, renewCmd, renewAllCmd)
}

// 打印证书信息
func printCertificateInfo(certInfo *cert_manager_wdd.CertInfo) {
	fmt.Printf("域名: %s\n", certInfo.Domain)
	fmt.Printf("注册时间: %s\n", certInfo.RegisteredAt.Format("2006-01-02 15:04:05"))
	fmt.Printf("到期时间: %s\n", certInfo.ExpiresAt.Format("2006-01-02 15:04:05"))
	fmt.Printf("剩余天数: %d\n", certInfo.DaysRemaining)
	fmt.Printf("证书路径: %s\n", certInfo.CertPath)
	fmt.Printf("密钥路径: %s\n", certInfo.KeyPath)
	fmt.Printf("CA服务器: %s\n", certInfo.CAName)
	fmt.Printf("是否需要更新: %v\n", certInfo.NeedsRenewal)
	fmt.Printf("是否为通配符证书: %v\n", certInfo.WildcardCert)
}

// 打印证书详细信息
func printCertificateDetailInfo(certInfo *cert_manager_wdd.CertInfo) {
	fmt.Printf("=============== 证书详情 ===============\n")
	printCertificateInfo(certInfo)
	fmt.Printf("=======================================\n")

	// 打印证书内容（可选）
	fmt.Printf("\n证书内容:\n")
	certContent, err := os.ReadFile(certInfo.CertPath)
	if err == nil {
		fmt.Println(string(certContent))
	} else {
		fmt.Printf("无法读取证书内容: %v\n", err)
	}
}

// 打印证书列表
func printCertificatesList(certs []cert_manager_wdd.CertInfo) {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
	fmt.Fprintln(w, "域名\t到期时间\t剩余天数\t需要更新\tCA服务器")
	fmt.Fprintln(w, "------\t--------\t--------\t--------\t--------")

	for _, cert := range certs {
		needsRenewal := "否"
		if cert.NeedsRenewal {
			needsRenewal = "是"
		}

		expiresAt := cert.ExpiresAt.Format("2006-01-02")
		fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\n",
			cert.Domain,
			expiresAt,
			cert.DaysRemaining,
			needsRenewal,
			cert.CAName)
	}

	w.Flush()
}
