package cmd

import (
	"agent-wdd/cloudflare"
	"agent-wdd/log"
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	"text/tabwriter"

	"github.com/spf13/cobra"
)

const (
	// Cloudflare API设置选项
	cfAPITokenDefault = "T7LxBemfe8SNGWkT9uz2XIc1e22ifAbBv_POJvDP" // 默认的API令牌，实际应用中应从配置文件或环境变量获取
)

// DNS记录类型常量
const (
	DNSTypeA     = "A"
	DNSTypeAAAA  = "AAAA"
	DNSTypeCNAME = "CNAME"
	DNSTypeTXT   = "TXT"
	DNSTypeMX    = "MX"
	DNSTypeSRV   = "SRV"
)

// 初始化Cloudflare客户端
func initCloudflareClient() *cloudflare.CloudflareClient {
	log.Debug("初始化Cloudflare客户端")
	return cloudflare.GetInstance(cfAPITokenDefault)
}

// 询问用户确认
func askForConfirmation(prompt string) bool {
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Printf("%s [y/n]: ", prompt)
		response, err := reader.ReadString('\n')
		if err != nil {
			log.Error("读取用户输入失败: %v", err)
			return false
		}

		response = strings.ToLower(strings.TrimSpace(response))
		if response == "y" || response == "yes" {
			return true
		} else if response == "n" || response == "no" {
			return false
		}
	}
}

// 添加Cloudflare命令
func addCloudflareSubcommands(cmd *cobra.Command) {
	// 域名管理命令
	domainCmd := &cobra.Command{
		Use:   "domain",
		Short: "Cloudflare域名管理",
		Long:  "管理Cloudflare上的域名（查询域名列表、查看域名详情等）",
	}

	// 域名列表命令
	listDomainsCmd := &cobra.Command{
		Use:   "list",
		Short: "列出所有域名",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("获取域名列表")
			client := initCloudflareClient()
			zones, err := client.ListZones(nil)
			if err != nil {
				log.Error("获取域名列表失败: %v", err)
				os.Exit(1)
			}

			if len(zones) == 0 {
				log.Info("未找到任何域名")
				return
			}

			printDomainsList(zones)
		},
	}

	// 查看域名详情命令
	getDomainCmd := &cobra.Command{
		Use:   "get [域名]",
		Short: "获取域名详情",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("获取域名详情: %s", domain)
			client := initCloudflareClient()
			zone, err := client.GetZone(domain)
			if err != nil {
				log.Error("获取域名详情失败: %v", err)
				os.Exit(1)
			}

			printDomainDetails(zone)
		},
	}

	// DNS记录管理命令
	dnsCmd := &cobra.Command{
		Use:   "dns",
		Short: "DNS记录管理",
		Long:  "管理Cloudflare上的DNS记录（查询、创建、更新、删除）",
	}

	// 列出DNS记录命令
	listDNSCmd := &cobra.Command{
		Use:   "list [域名]",
		Short: "列出域名的所有DNS记录",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("获取域名 %s 的DNS记录", domain)
			client := initCloudflareClient()

			// 先获取zone ID
			zone, err := client.GetZone(domain)
			if err != nil {
				log.Error("获取域名信息失败: %v", err)
				os.Exit(1)
			}

			records, err := client.ListDNSRecords(zone.ID, nil)
			if err != nil {
				log.Error("获取DNS记录失败: %v", err)
				os.Exit(1)
			}

			if len(records) == 0 {
				log.Info("未找到任何DNS记录")
				return
			}

			printDNSRecordsList(records, domain)
		},
	}

	// 创建DNS记录命令
	createDNSCmd := &cobra.Command{
		Use:   "create [域名]",
		Short: "创建DNS记录",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("为域名 %s 创建DNS记录", domain)
			client := initCloudflareClient()

			// 先获取zone ID
			zone, err := client.GetZone(domain)
			if err != nil {
				log.Error("获取域名信息失败: %v", err)
				os.Exit(1)
			}

			// 交互式收集DNS记录信息
			record, err := collectDNSRecordInfo(domain)
			if err != nil {
				log.Error("收集DNS记录信息失败: %v", err)
				os.Exit(1)
			}

			// 确认信息
			fmt.Println("\n即将创建以下DNS记录:")
			fmt.Printf("名称: %s\n", record.Name)
			fmt.Printf("类型: %s\n", record.Type)
			fmt.Printf("内容: %s\n", record.Content)
			fmt.Printf("TTL: %d\n", record.TTL)
			if record.Priority > 0 {
				fmt.Printf("优先级: %d\n", record.Priority)
			}
			fmt.Printf("代理状态: %v\n", record.Proxied)

			if !askForConfirmation("确认创建此DNS记录?") {
				log.Info("已取消创建DNS记录")
				return
			}

			// 创建DNS记录
			createdRecord, err := client.CreateDNSRecord(zone.ID, record)
			if err != nil {
				log.Error("创建DNS记录失败: %v", err)
				os.Exit(1)
			}

			log.Info("DNS记录创建成功")
			printDNSRecordDetails(createdRecord, domain)
		},
	}

	// 更新DNS记录命令
	updateDNSCmd := &cobra.Command{
		Use:   "update [域名]",
		Short: "更新DNS记录",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("更新域名 %s 的DNS记录", domain)
			client := initCloudflareClient()

			// 先获取zone ID
			zone, err := client.GetZone(domain)
			if err != nil {
				log.Error("获取域名信息失败: %v", err)
				os.Exit(1)
			}

			// 获取域名到ID的映射
			dnsNameToIDMap := client.GetDNSNameToIDMap(zone.ID)
			if len(dnsNameToIDMap) == 0 {
				log.Error("未找到ZoneID %s Zone %s 的任何DNS记录", zone.ID, zone.Name)
				os.Exit(1)
			}

			// recordID 为空，则获取所有DNS记录
			recordID := dnsNameToIDMap[domain]
			if recordID == "" {
				log.Error("未找到zoneID %s Zone %s 域名 %s 的DNS记录", zone.ID, zone.Name, domain)
				os.Exit(1)
			}

			// 获取当前记录
			currentRecord, err := client.GetDNSRecord(zone.ID, recordID)
			if err != nil {
				log.Error("获取DNS记录失败: %v", err)
				os.Exit(1)
			}

			// 显示当前记录
			fmt.Println("当前DNS记录:")
			printDNSRecordDetails(currentRecord, domain)

			// 交互式收集更新后的DNS记录信息
			updatedRecord, err := updateDNSRecordInfo(*currentRecord)
			if err != nil {
				log.Error("收集DNS记录更新信息失败: %v", err)
				os.Exit(1)
			}

			// 确认信息
			fmt.Println("\n即将更新为以下DNS记录:")
			fmt.Printf("名称: %s\n", updatedRecord.Name)
			fmt.Printf("类型: %s\n", updatedRecord.Type)
			fmt.Printf("内容: %s\n", updatedRecord.Content)
			fmt.Printf("TTL: %d\n", updatedRecord.TTL)
			if updatedRecord.Priority > 0 {
				fmt.Printf("优先级: %d\n", updatedRecord.Priority)
			}
			fmt.Printf("代理状态: %v\n", updatedRecord.Proxied)

			if !askForConfirmation("确认更新此DNS记录?") {
				log.Info("已取消更新DNS记录")
				return
			}

			// 更新DNS记录
			updatedRecordResult, err := client.UpdateDNSRecord(zone.ID, recordID, updatedRecord)
			if err != nil {
				log.Error("更新DNS记录失败: %v", err)
				os.Exit(1)
			}

			log.Info("DNS记录更新成功")
			printDNSRecordDetails(updatedRecordResult, domain)
		},
	}

	// 删除DNS记录命令
	deleteDNSCmd := &cobra.Command{
		Use:   "delete [域名]",
		Short: "删除DNS记录",
		Args:  cobra.ExactArgs(1),
		Run: func(cmd *cobra.Command, args []string) {
			domain := args[0]
			log.Info("删除域名 %s 的DNS记录", domain)
			client := initCloudflareClient()

			// 先获取zone ID
			zone, err := client.GetZone(domain)
			if err != nil {
				log.Error("获取域名信息失败: %v", err)
				os.Exit(1)
			}

			// 获取域名到ID的映射
			dnsNameToIDMap := client.GetDNSNameToIDMap(zone.ID)
			if len(dnsNameToIDMap) == 0 {
				log.Error("未找到ZoneID %s Zone %s 的任何DNS记录", zone.ID, zone.Name)
				os.Exit(1)
			}

			// recordID 为空，则获取所有DNS记录
			recordID := dnsNameToIDMap[domain]
			if recordID == "" {
				log.Error("未找到zoneID %s Zone %s 域名 %s 的DNS记录", zone.ID, zone.Name, domain)
				os.Exit(1)
			}

			// 获取要删除的记录信息
			record, err := client.GetDNSRecord(zone.ID, recordID)
			if err != nil {
				log.Error("获取DNS记录信息失败: %v", err)
				os.Exit(1)
			}

			// 显示要删除的记录
			fmt.Println("即将删除以下DNS记录:")
			printDNSRecordDetails(record, domain)

			// 请求确认
			if !askForConfirmation("确认删除此DNS记录? 此操作不可恢复!") {
				log.Info("已取消删除DNS记录")
				return
			}

			// 二次确认
			fmt.Println("\n⚠️  警告: 删除DNS记录可能会影响网站访问、邮件服务等功能")
			if !askForConfirmation("再次确认删除此DNS记录?") {
				log.Info("已取消删除DNS记录")
				return
			}

			// 删除DNS记录
			success, err := client.DeleteDNSRecord(zone.ID, recordID)
			if err != nil {
				log.Error("删除DNS记录失败: %v", err)
				os.Exit(1)
			}

			if success {
				log.Info("DNS记录删除成功")
			} else {
				log.Error("DNS记录删除失败")
				os.Exit(1)
			}
		},
	}

	// 添加域名管理子命令
	domainCmd.AddCommand(listDomainsCmd, getDomainCmd)

	// 添加DNS管理子命令
	dnsCmd.AddCommand(listDNSCmd, createDNSCmd, updateDNSCmd, deleteDNSCmd)

	// 将所有主要命令添加到父命令
	cmd.AddCommand(domainCmd, dnsCmd)
}

// 打印域名列表
func printDomainsList(zones []cloudflare.Zone) {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
	fmt.Fprintln(w, "域名\t状态\t名称服务器\t创建时间")
	fmt.Fprintln(w, "----\t----\t---------\t--------")

	for _, zone := range zones {
		nameServers := strings.Join(zone.NameServers, ", ")
		createdOn := zone.CreatedOn[:10] // 仅显示日期部分
		status := zone.Status
		if zone.Paused {
			status += " (已暂停)"
		}

		fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
			zone.Name,
			status,
			nameServers,
			createdOn)
	}

	w.Flush()
}

// 打印域名详情
func printDomainDetails(zone *cloudflare.Zone) {
	fmt.Printf("================== 域名详情 ==================\n")
	fmt.Printf("域名: %s\n", zone.Name)
	fmt.Printf("ID: %s\n", zone.ID)
	fmt.Printf("状态: %s\n", zone.Status)
	fmt.Printf("暂停: %v\n", zone.Paused)
	fmt.Printf("类型: %s\n", zone.Type)
	fmt.Printf("开发模式: %d\n", zone.DevelopmentMode)
	fmt.Printf("名称服务器: %s\n", strings.Join(zone.NameServers, ", "))
	fmt.Printf("原始名称服务器: %s\n", strings.Join(zone.OriginalNameServers, ", "))
	fmt.Printf("修改时间: %s\n", zone.ModifiedOn)
	fmt.Printf("创建时间: %s\n", zone.CreatedOn)
	fmt.Printf("激活时间: %s\n", zone.ActivatedOn)
	if zone.Account.Name != "" {
		fmt.Printf("账户: %s (%s)\n", zone.Account.Name, zone.Account.ID)
	}
	fmt.Printf("==================================================\n")
}

// 打印DNS记录列表
func printDNSRecordsList(records []cloudflare.DNSRecord, domain string) {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
	fmt.Fprintf(w, "域名: %s\n\n", domain)
	fmt.Fprintln(w, "名称\t类型\t内容\tTTL\t代理\t优先级\t备注")
	fmt.Fprintln(w, "----\t----\t----\t---\t----\t-----\t----")

	for _, record := range records {
		ttl := "自动"
		if record.TTL > 1 {
			ttl = strconv.Itoa(record.TTL)
		}

		priority := "-"
		if record.Priority > 0 {
			priority = strconv.Itoa(record.Priority)
		}

		proxied := "否"
		if record.Proxied {
			proxied = "是"
		}

		fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
			record.Name,
			record.Type,
			record.Content,
			ttl,
			proxied,
			priority,
			record.Comment)
	}

	w.Flush()
}

// 打印DNS记录详情
func printDNSRecordDetails(record *cloudflare.DNSRecord, domain string) {
	fmt.Printf("================ DNS记录详情 ================\n")
	fmt.Printf("域名: %s\n", domain)
	fmt.Printf("ID: %s\n", record.ID)
	fmt.Printf("名称: %s\n", record.Name)
	fmt.Printf("类型: %s\n", record.Type)
	fmt.Printf("内容: %s\n", record.Content)

	ttl := "自动"
	if record.TTL > 1 {
		ttl = strconv.Itoa(record.TTL)
	}
	fmt.Printf("TTL: %s\n", ttl)

	fmt.Printf("代理: %v\n", record.Proxied)

	if record.Priority > 0 {
		fmt.Printf("优先级: %d\n", record.Priority)
	}

	if record.Comment != "" {
		fmt.Printf("备注: %s\n", record.Comment)
	}

	if record.CreatedOn != "" {
		fmt.Printf("创建时间: %s\n", record.CreatedOn)
	}

	if record.ModifiedOn != "" {
		fmt.Printf("修改时间: %s\n", record.ModifiedOn)
	}
	fmt.Printf("==============================================\n")
}

// 交互式收集DNS记录信息
func collectDNSRecordInfo(domain string) (cloudflare.DNSRecord, error) {
	reader := bufio.NewReader(os.Stdin)
	record := cloudflare.DNSRecord{
		Proxied: false, // 默认不代理
		TTL:     1,     // 默认自动TTL
	}

	// 获取记录名称
	fmt.Print("请输入记录名称 (例如: www): ")
	name, err := reader.ReadString('\n')
	if err != nil {
		return record, fmt.Errorf("读取输入失败: %w", err)
	}
	name = strings.TrimSpace(name)

	// 如果用户仅输入@，则使用根域名
	if name == "@" {
		record.Name = domain
	} else if name != "" {
		// 否则添加域名后缀
		record.Name = name + "." + domain
	} else {
		return record, fmt.Errorf("记录名称不能为空")
	}

	// 获取记录类型
	fmt.Printf("请选择记录类型:\n")
	fmt.Printf("1) A (IPv4地址)\n")
	fmt.Printf("2) AAAA (IPv6地址)\n")
	fmt.Printf("3) CNAME (别名)\n")
	fmt.Printf("4) TXT (文本记录)\n")
	fmt.Printf("5) MX (邮件服务器)\n")
	fmt.Printf("6) SRV (服务记录)\n")
	fmt.Print("请输入选项 (1-6): ")
	typeChoice, err := reader.ReadString('\n')
	if err != nil {
		return record, fmt.Errorf("读取输入失败: %w", err)
	}
	typeChoice = strings.TrimSpace(typeChoice)

	switch typeChoice {
	case "1":
		record.Type = DNSTypeA
	case "2":
		record.Type = DNSTypeAAAA
	case "3":
		record.Type = DNSTypeCNAME
	case "4":
		record.Type = DNSTypeTXT
	case "5":
		record.Type = DNSTypeMX
	case "6":
		record.Type = DNSTypeSRV
	default:
		return record, fmt.Errorf("无效的记录类型选择")
	}

	// 获取记录内容
	fmt.Printf("请输入记录内容 (%s): ", getContentHint(record.Type))
	content, err := reader.ReadString('\n')
	if err != nil {
		return record, fmt.Errorf("读取输入失败: %w", err)
	}
	content = strings.TrimSpace(content)
	if content == "" {
		return record, fmt.Errorf("记录内容不能为空")
	}
	record.Content = content

	// 对于MX记录，获取优先级
	if record.Type == DNSTypeMX {
		fmt.Print("请输入优先级 (1-100，默认10): ")
		priorityStr, err := reader.ReadString('\n')
		if err != nil {
			return record, fmt.Errorf("读取输入失败: %w", err)
		}
		priorityStr = strings.TrimSpace(priorityStr)

		priority := 10 // 默认优先级
		if priorityStr != "" {
			p, err := strconv.Atoi(priorityStr)
			if err != nil {
				return record, fmt.Errorf("无效的优先级: %w", err)
			}
			if p < 1 || p > 100 {
				return record, fmt.Errorf("优先级必须在1到100之间")
			}
			priority = p
		}
		record.Priority = priority
	}

	// 获取TTL
	fmt.Print("请输入TTL (1表示自动，最小值120，建议值1800或3600): ")
	ttlStr, err := reader.ReadString('\n')
	if err != nil {
		return record, fmt.Errorf("读取输入失败: %w", err)
	}
	ttlStr = strings.TrimSpace(ttlStr)

	if ttlStr != "" {
		ttl, err := strconv.Atoi(ttlStr)
		if err != nil {
			return record, fmt.Errorf("无效的TTL: %w", err)
		}
		if ttl != 1 && ttl < 120 {
			return record, fmt.Errorf("TTL不能小于120")
		}
		record.TTL = ttl
	}

	// 对于A，AAAA或CNAME记录，询问是否代理
	if record.Type == DNSTypeA || record.Type == DNSTypeAAAA || record.Type == DNSTypeCNAME {
		fmt.Print("是否通过Cloudflare代理 (y/n，默认n): ")
		proxyStr, err := reader.ReadString('\n')
		if err != nil {
			return record, fmt.Errorf("读取输入失败: %w", err)
		}
		proxyStr = strings.ToLower(strings.TrimSpace(proxyStr))
		if proxyStr == "y" || proxyStr == "yes" {
			record.Proxied = true
		}
	}

	// 获取备注（可选）
	fmt.Print("请输入备注 (可选): ")
	comment, err := reader.ReadString('\n')
	if err != nil {
		return record, fmt.Errorf("读取输入失败: %w", err)
	}
	comment = strings.TrimSpace(comment)
	if comment != "" {
		record.Comment = comment
	}

	return record, nil
}

// 更新DNS记录信息
func updateDNSRecordInfo(currentRecord cloudflare.DNSRecord) (cloudflare.DNSRecord, error) {
	reader := bufio.NewReader(os.Stdin)
	updatedRecord := currentRecord

	// 获取记录内容
	fmt.Printf("请输入新的记录内容 (%s) [当前值: %s]: ", getContentHint(currentRecord.Type), currentRecord.Content)
	content, err := reader.ReadString('\n')
	if err != nil {
		return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
	}
	content = strings.TrimSpace(content)
	if content != "" {
		updatedRecord.Content = content
	}

	// 对于MX记录，获取优先级
	if currentRecord.Type == DNSTypeMX {
		fmt.Printf("请输入新的优先级 (1-100) [当前值: %d]: ", currentRecord.Priority)
		priorityStr, err := reader.ReadString('\n')
		if err != nil {
			return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
		}
		priorityStr = strings.TrimSpace(priorityStr)

		if priorityStr != "" {
			p, err := strconv.Atoi(priorityStr)
			if err != nil {
				return updatedRecord, fmt.Errorf("无效的优先级: %w", err)
			}
			if p < 1 || p > 100 {
				return updatedRecord, fmt.Errorf("优先级必须在1到100之间")
			}
			updatedRecord.Priority = p
		}
	}

	// 获取TTL
	ttlStr := "自动"
	if currentRecord.TTL > 1 {
		ttlStr = strconv.Itoa(currentRecord.TTL)
	}
	fmt.Printf("请输入新的TTL (1表示自动，最小值120，建议值1800或3600) [当前值: %s]: ", ttlStr)
	newTTLStr, err := reader.ReadString('\n')
	if err != nil {
		return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
	}
	newTTLStr = strings.TrimSpace(newTTLStr)

	if newTTLStr != "" {
		ttl, err := strconv.Atoi(newTTLStr)
		if err != nil {
			return updatedRecord, fmt.Errorf("无效的TTL: %w", err)
		}
		if ttl != 1 && ttl < 120 {
			return updatedRecord, fmt.Errorf("TTL不能小于120")
		}
		updatedRecord.TTL = ttl
	}

	// 对于A，AAAA或CNAME记录，询问是否代理
	if currentRecord.Type == DNSTypeA || currentRecord.Type == DNSTypeAAAA || currentRecord.Type == DNSTypeCNAME {
		proxyStr := "n"
		if currentRecord.Proxied {
			proxyStr = "y"
		}
		fmt.Printf("是否通过Cloudflare代理 (y/n) [当前值: %s]: ", proxyStr)
		newProxyStr, err := reader.ReadString('\n')
		if err != nil {
			return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
		}
		newProxyStr = strings.ToLower(strings.TrimSpace(newProxyStr))
		if newProxyStr != "" {
			if newProxyStr == "y" || newProxyStr == "yes" {
				updatedRecord.Proxied = true
			} else if newProxyStr == "n" || newProxyStr == "no" {
				updatedRecord.Proxied = false
			}
		}
	}

	// 获取备注（可选）
	fmt.Printf("请输入新的备注 (可选) [当前值: %s]: ", currentRecord.Comment)
	comment, err := reader.ReadString('\n')
	if err != nil {
		return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
	}
	comment = strings.TrimSpace(comment)
	if comment != "" {
		updatedRecord.Comment = comment
	}

	return updatedRecord, nil
}

// 根据记录类型获取内容提示
func getContentHint(recordType string) string {
	switch recordType {
	case DNSTypeA:
		return "IPv4地址，例如: 192.168.1.1"
	case DNSTypeAAAA:
		return "IPv6地址，例如: 2001:db8::1"
	case DNSTypeCNAME:
		return "域名，例如: example.com"
	case DNSTypeTXT:
		return "文本内容"
	case DNSTypeMX:
		return "邮件服务器域名，例如: mail.example.com"
	case DNSTypeSRV:
		return "SRV记录，例如: 10 5 5060 sip.example.com"
	default:
		return "记录内容"
	}
}
