package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	// MySQL连接信息
	username := "root"
	password := "root"
	hostname := "127.0.0.1"
	port := "3306"

	// 构建DSN (Data Source Name) - 首先连接到MySQL服务器，不指定数据库
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/", username, password, hostname, port)

	// 连接到MySQL服务器
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		log.Fatalf("Failed to open database connection: %v", err)
	}
	defer db.Close()

	// 测试连接
	if err := db.Ping(); err != nil {
		log.Fatalf("Failed to ping database: %v", err)
	}

	fmt.Println("Connected to MySQL server successfully!")

	// 1. 检查数据库是否存在
	var dbExists bool
	checkDBQuery := "SELECT COUNT(*) > 0 FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'nl_blog'"
	err = db.QueryRow(checkDBQuery).Scan(&dbExists)
	if err != nil {
		log.Fatalf("Failed to check database existence: %v", err)
	}

	if dbExists {
		fmt.Println("✅ Database 'nl_blog' exists!")
	} else {
		log.Fatalf("❌ Database 'nl_blog' does not exist!")
	}

	// 2. 连接到nl_blog数据库
	dsnWithDB := fmt.Sprintf("%s:%s@tcp(%s:%s)/nl_blog", username, password, hostname, port)
	db, err = sql.Open("mysql", dsnWithDB)
	if err != nil {
		log.Fatalf("Failed to open database connection to nl_blog: %v", err)
	}
	defer db.Close()

	if err := db.Ping(); err != nil {
		log.Fatalf("Failed to ping nl_blog database: %v", err)
	}

	fmt.Println("Connected to 'nl_blog' database successfully!")

	// 3. 查询数据库中的所有表
	showTablesQuery := "SHOW TABLES"
	rows, err := db.Query(showTablesQuery)
	if err != nil {
		log.Fatalf("Failed to show tables: %v", err)
	}
	defer rows.Close()

	fmt.Println("\nTables in 'nl_blog' database:")
	var tableName string
	tableCount := 0
	for rows.Next() {
		if err := rows.Scan(&tableName); err != nil {
			log.Fatalf("Failed to scan table name: %v", err)
		}
		fmt.Printf("✅ %s\n", tableName)
		tableCount++
	}

	if tableCount == 0 {
		log.Fatalf("❌ No tables found in 'nl_blog' database!")
	} else {
		fmt.Printf("\nTotal tables: %d\n", tableCount)
	}

	// 4. 检查主要表的结构和数据
	checkTableStructure(db, "works")
	checkTableStructure(db, "posts")
	checkTableStructure(db, "snippets")
	checkTableStructure(db, "users")
	checkTableStructure(db, "settings")

	fmt.Println("\n✅ Database verification completed successfully!")
}

// 检查表结构和数据
func checkTableStructure(db *sql.DB, tableName string) {
	fmt.Printf("\n--- Checking table: %s ---", tableName)

	// 检查表是否存在
	var tableExists bool
	checkTableQuery := "SELECT COUNT(*) > 0 FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'nl_blog' AND TABLE_NAME = ?"
	err := db.QueryRow(checkTableQuery, tableName).Scan(&tableExists)
	if err != nil {
		log.Fatalf("Failed to check table existence: %v", err)
	}

	if !tableExists {
		log.Fatalf("❌ Table '%s' does not exist!", tableName)
	}

	// 查询表中的记录数量
	var count int
	countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName)
	err = db.QueryRow(countQuery).Scan(&count)
	if err != nil {
		log.Fatalf("Failed to count rows in table '%s': %v", tableName, err)
	}

	fmt.Printf("\n✅ Table '%s' exists with %d records", tableName, count)

	// 查询表结构（前5个字段）
	// 简化查询，只获取字段名、类型、是否为空和键信息，不获取默认值和额外信息
	schemaQuery := `SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_KEY 
		FROM information_schema.COLUMNS 
		WHERE TABLE_SCHEMA = 'nl_blog' AND TABLE_NAME = ? 
		ORDER BY ORDINAL_POSITION 
		LIMIT 5`
	rows, err := db.Query(schemaQuery, tableName)
	if err != nil {
		log.Fatalf("Failed to get schema for table '%s': %v", tableName, err)
	}
	defer rows.Close()

	fmt.Println("\nTable structure (top 5 fields):")
	var field, fieldType, null, key string
	for rows.Next() {
		if err := rows.Scan(&field, &fieldType, &null, &key); err != nil {
			log.Fatalf("Failed to scan field: %v", err)
		}
		fmt.Printf("  %s | %s | %s | %s\n", field, fieldType, null, key)
	}

	// 如果是posts表，查询前2条记录
	if tableName == "posts" && count > 0 {
		fmt.Println("\nSample data (top 2 records):")
		sampleQuery := "SELECT id, title, category, date FROM posts ORDER BY date DESC LIMIT 2"
		rows, err := db.Query(sampleQuery)
		if err != nil {
			log.Fatalf("Failed to get sample data from '%s': %v", tableName, err)
		}
		defer rows.Close()

		var id, title, category, date string
		for rows.Next() {
			if err := rows.Scan(&id, &title, &category, &date); err != nil {
				log.Fatalf("Failed to scan sample data: %v", err)
			}
			fmt.Printf("  ID: %s | Title: %s | Category: %s | Date: %s\n", id, title, category, date)
		}
	}
}
