package scripts

import (
	"cmdb-backend/models"
	"cmdb-backend/pkg/config"
	"fmt"
	"time"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323"
)

// RunAnalysis 分析指定域名的数据差异
func RunAnalysis() {
	// ===== 在这里修改要分析的域名 =====
	targetZone := "pingcap.cloud"  // 改成你要分析的域名，空字符串表示分析所有域名
	// ================================
	
	fmt.Println("开始分析DNSpod和CMDB数据差异")
	if targetZone != "" {
		fmt.Printf("目标域名: %s\n", targetZone)
	}
	fmt.Println("只读模式，不修改数据")
	
	client := createDnsPodClient()
	
	// 获取DNSpod域名列表
	zones, err := fetchDnsPodZones(client)
	if err != nil {
		fmt.Printf("获取域名列表失败: %v\n", err)
		return
	}
	
	// 分析每个域名
	for _, zone := range zones {
		zoneName := *zone.Name
		
		// 如果指定了域名，只处理该域名
		if targetZone != "" && zoneName != targetZone {
			continue
		}
		
		fmt.Printf("\n域名: %s\n", zoneName)
		
		// 获取DNSpod记录
		dnspodRecords, err := fetchDnsPodRecords(client, zoneName)
		if err != nil {
			fmt.Printf("获取DNSpod记录失败: %v\n", err)
			continue
		}
		
		// 获取CMDB记录
		cmdbRecords := getCmdbTencentRecords(zoneName)
		
		fmt.Printf("DNSpod记录数: %d\n", len(dnspodRecords))
		fmt.Printf("CMDB记录数: %d\n", len(cmdbRecords))
		
		// 找出缺失的记录 (DNSpod有，CMDB没有 - 需要新增)
		missingInCmdb := 0
		fmt.Println("\n需要新增的记录 (DNSpod有，CMDB没有):")
		for _, record := range dnspodRecords {
			recordId := int64(*record.RecordId)
			if _, exists := cmdbRecords[recordId]; !exists {
				missingInCmdb++
				// 尝试获取备注字段，可能叫 Remark 或 Memo
				remark := ""
				if record.Remark != nil {
					remark = *record.Remark
				}
				fmt.Printf("  [%d] %s.%s %s -> %s (remark: %s)\n", 
					recordId, *record.Name, zoneName, *record.Type, *record.Value, remark)
			}
		}
		
		if missingInCmdb == 0 {
			fmt.Println("  无需新增记录")
		} else {
			fmt.Printf("需要新增: %d 条\n", missingInCmdb)
		}
		
		// 找出多余的记录 (CMDB有，DNSpod没有 - 需要删除)
		extraInCmdb := 0
		fmt.Println("\n需要删除的记录 (CMDB有，DNSpod没有):")
		
		// 先构建DNSpod记录的recordId集合，便于查找
		dnspodRecordIds := make(map[int64]bool)
		for _, record := range dnspodRecords {
			recordId := int64(*record.RecordId)
			dnspodRecordIds[recordId] = true
		}
		
		// 检查CMDB中的记录
		for recordId, cmdbRecord := range cmdbRecords {
			if !dnspodRecordIds[recordId] {
				extraInCmdb++
				fmt.Printf("  [%d] %s.%s %s -> %s (owner: %s, remark: %s)\n", 
					recordId, cmdbRecord.Name, zoneName, cmdbRecord.Type, 
					cmdbRecord.Target, cmdbRecord.Owner, cmdbRecord.Remark)
			}
		}
		
		if extraInCmdb == 0 {
			fmt.Println("  无需删除记录")
		} else {
			fmt.Printf("需要删除: %d 条\n", extraInCmdb)
		}
		
		// 如果指定了域名，处理完就退出
		if targetZone != "" {
			break
		}
	}
	
	fmt.Println("分析完成")
}

// RunSync 同步指定域名的缺失记录
func RunSync() {
	// ===== 在这里修改要同步的域名 =====
	targetZone := "pingcap.net"  // 改成你要同步的域名
	// ================================
	
	fmt.Printf("开始同步域名: %s\n", targetZone)
	fmt.Println("注意: 这将修改数据库!")
	
	client := createDnsPodClient()
	
	// 获取DNSpod记录
	dnspodRecords, err := fetchDnsPodRecords(client, targetZone)
	if err != nil {
		fmt.Printf("获取DNSpod记录失败: %v\n", err)
		return
	}
	
	// 获取CMDB记录
	cmdbRecords := getCmdbTencentRecords(targetZone)
	
	fmt.Printf("DNSpod记录数: %d\n", len(dnspodRecords))
	fmt.Printf("CMDB记录数: %d\n", len(cmdbRecords))
	
	// 创建DNSpod记录ID集合，用于验证记录有效性
	dnspodRecordIds := make(map[int64]bool)
	for _, record := range dnspodRecords {
		dnspodRecordIds[int64(*record.RecordId)] = true
	}
	
	// 处理记录：新增和更新
	addedCount := 0
	updatedCount := 0
	fmt.Println("\n开始处理记录差异:")
	
	// 1. 处理DNSpod中的记录（新增或更新）
	for _, record := range dnspodRecords {
		recordId := int64(*record.RecordId)
		
		remark := ""
		if record.Remark != nil {
			remark = *record.Remark
		}
		
		// 转换时间格式
		updatedTime, err := time.Parse("2006-01-02 15:04:05", *record.UpdatedOn)
		if err != nil {
			fmt.Printf("  时间格式转换失败 [%d]: %v，使用当前时间\n", recordId, err)
			updatedTime = time.Now()
		}
		
		if existingRecord, exists := cmdbRecords[recordId]; exists {
			// 记录存在，检查是否需要更新
			if needsRecordUpdate(existingRecord, record, remark) {
				fmt.Printf("  需要更新 [%d] %s.%s\n", recordId, *record.Name, targetZone)
				
				// 只显示有差异的字段
				diffCount := 0
				if existingRecord.Name != *record.Name {
					fmt.Printf("    Name: '%s' -> '%s'\n", existingRecord.Name, *record.Name)
					diffCount++
				}
				if existingRecord.Type != *record.Type {
					fmt.Printf("    Type: '%s' -> '%s'\n", existingRecord.Type, *record.Type)
					diffCount++
				}
				if existingRecord.Line != *record.Line {
					fmt.Printf("    Line: '%s' -> '%s'\n", existingRecord.Line, *record.Line)
					diffCount++
				}
				if existingRecord.Ttl != int(*record.TTL) {
					fmt.Printf("    Ttl: %d -> %d\n", existingRecord.Ttl, int(*record.TTL))
					diffCount++
				}
				if existingRecord.Target != *record.Value {
					fmt.Printf("    Target: '%s' -> '%s'\n", existingRecord.Target, *record.Value)
					diffCount++
				}
				if existingRecord.Status != *record.Status {
					fmt.Printf("    Status: '%s' -> '%s'\n", existingRecord.Status, *record.Status)
					diffCount++
				}
				// 不显示 Remark 字段差异
				
				fmt.Printf("    共%d个字段有差异\n", diffCount)
				
				// 智能更新：只更新技术字段，保留管理字段
				updateErr := smartUpdateDnsRecord(existingRecord, record, remark, updatedTime)
				if updateErr != nil {
					fmt.Printf("    更新失败: %v\n", updateErr)
				} else {
					updatedCount++
					fmt.Printf("    ✓ 已更新\n")
				}
			}
		} else {
			// 记录不存在，新增
			fmt.Printf("  需要新增 [%d] %s.%s %s->%s Remark:%s\n", 
				recordId, *record.Name, targetZone, *record.Type, *record.Value, remark)
			
			newRecord := models.DnsRecord{
				RecordId:   recordId,
				ZoneName:   targetZone,
				Name:       *record.Name,
				Type:       *record.Type,
				Line:       *record.Line,
				VendorId:   5,
				Ttl:        int(*record.TTL),
				Target:     *record.Value,
				Status:     *record.Status,
				Owner:      "",  // 空字符串，便于在页面识别待认领记录
				Remark:     remark,
				UpdateTime: updatedTime,  // 使用DNSpod的UpdatedOn时间
				CreateTime: time.Now(),   // 设置为当前时间
			}
			
			insertErr := models.CreateDnsRecord(&newRecord)
			if insertErr != nil {
				fmt.Printf("    插入失败: %v\n", insertErr)
			} else {
				addedCount++
				fmt.Printf("    ✓ 已插入\n")
			}
		}
	}
	
	// 2. 检查CMDB中多余的记录（DNSpod中不存在的，可能需要删除）
	invalidCount := 0
	fmt.Println("\n检查无效记录 (CMDB有但DNSpod没有):")
	for recordId, cmdbRecord := range cmdbRecords {
		if !dnspodRecordIds[recordId] {
			invalidCount++
			fmt.Printf("  ⚠️  无效记录 [%d] %s.%s\n", 
				recordId, cmdbRecord.Name, cmdbRecord.ZoneName)
			fmt.Printf("      类型: %s | 目标: %s | TTL: %d | 线路: %s | 状态: %s\n", 
				cmdbRecord.Type, cmdbRecord.Target, cmdbRecord.Ttl, cmdbRecord.Line, cmdbRecord.Status)
			fmt.Printf("      负责人: %s | 备注: %s | 更新时间: %s\n", 
				cmdbRecord.Owner, cmdbRecord.Remark, cmdbRecord.UpdateTime.Format("2006-01-02 15:04:05"))
			fmt.Printf("      >> 建议删除：DNSpod中不存在此记录\n")
			fmt.Println()
		}
	}
	
	fmt.Printf("\n=== 同步完成 ===\n")
	fmt.Printf("域名: %s\n", targetZone)
	fmt.Printf("新增: %d 条\n", addedCount)
	fmt.Printf("更新: %d 条\n", updatedCount)
	if invalidCount > 0 {
		fmt.Printf("发现无效记录: %d 条 (建议删除)\n", invalidCount)
	}
}

// needsRecordUpdate 检查记录是否需要更新（精确比较，不比较UpdateTime和Remark）
func needsRecordUpdate(existing models.DnsRecord, dnspodRecord *dnspod.RecordListItem, remark string) bool {
	// 只比较核心技术字段（不比较UpdateTime和Remark）
	if existing.Name != *dnspodRecord.Name {
		return true
	}
	if existing.Type != *dnspodRecord.Type {
		return true
	}
	if existing.Line != *dnspodRecord.Line {
		return true
	}
	if existing.Ttl != int(*dnspodRecord.TTL) {
		return true
	}
	if existing.Target != *dnspodRecord.Value {
		return true
	}
	if existing.Status != *dnspodRecord.Status {
		return true
	}
	// 不比较 Remark 字段
	
	return false
}

// smartUpdateDnsRecord 智能更新记录（只更新技术字段，保留管理字段）
func smartUpdateDnsRecord(existing models.DnsRecord, dnspodRecord *dnspod.RecordListItem, remark string, updatedTime time.Time) error {
	// 只更新核心技术字段，保留管理字段 (Owner, Remark 保持不变)
	err := models.UpdateDnsRecords(existing.Id, 
		*dnspodRecord.Name,    // Name
		*dnspodRecord.Type,    // Type  
		*dnspodRecord.Value,   // Target
		int(*dnspodRecord.TTL), // Ttl
		*dnspodRecord.Line,    // Line
		existing.Owner,        // 保持原有Owner不变
		existing.Remark,       // 保持原有Remark不变
		[]int{})               // 空数组表示单条更新
	
	if err != nil {
		return fmt.Errorf("更新记录失败: %v", err)
	}
	
	return nil
}

// 创建DNSpod客户端
func createDnsPodClient() *dnspod.Client {
	credential := common.NewCredential(
		config.GC.Vendor.TencentAk,
		config.GC.Vendor.TencentSk,
	)
	
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "dnspod.tencentcloudapi.com"
	
	client, _ := dnspod.NewClient(credential, "", cpf)
	return client
}

// 获取DNSpod所有域名
func fetchDnsPodZones(client *dnspod.Client) ([]*dnspod.DomainListItem, error) {
	request := dnspod.NewDescribeDomainListRequest()
	response, err := client.DescribeDomainList(request)
	if err != nil {
		return nil, err
	}
	return response.Response.DomainList, nil
}

// 获取DNSpod指定域名的DNS记录
func fetchDnsPodRecords(client *dnspod.Client, domain string) ([]*dnspod.RecordListItem, error) {
	request := dnspod.NewDescribeRecordListRequest()
	request.Domain = common.StringPtr(domain)
	request.Limit = common.Uint64Ptr(3000)
	
	response, err := client.DescribeRecordList(request)
	if err != nil {
		return nil, err
	}
	return response.Response.RecordList, nil
}

// 获取CMDB中指定域名的腾讯DNS记录
func getCmdbTencentRecords(zoneName string) map[int64]models.DnsRecord {
	allRecords := models.GetDnsRecord(zoneName, "", "", "", 0, 10000, "")  // 分页从0开始
	
	recordMap := make(map[int64]models.DnsRecord)
	for _, record := range allRecords {
		if record.VendorId == 5 { // 只要腾讯DNS记录
			recordMap[record.RecordId] = record
		}
	}
	
	return recordMap
}