package main

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

	"nofx/crypto"

	_ "modernc.org/sqlite"
)

func main() {
	log.Println("🔄 開始遷移數據庫到加密格式...")

	// 1. 檢查數據庫檔案
	dbPath := "config.db"
	if len(os.Args) > 1 {
		dbPath = os.Args[1]
	}

	if _, err := os.Stat(dbPath); os.IsNotExist(err) {
		log.Fatalf("❌ 數據庫檔案不存在: %s", dbPath)
	}

	// 2. 備份數據庫
	backupPath := fmt.Sprintf("%s.pre_encryption_backup", dbPath)
	log.Printf("📦 備份數據庫到: %s", backupPath)

	input, err := os.ReadFile(dbPath)
	if err != nil {
		log.Fatalf("❌ 讀取數據庫失敗: %v", err)
	}

	if err := os.WriteFile(backupPath, input, 0600); err != nil {
		log.Fatalf("❌ 備份失敗: %v", err)
	}

	// 3. 打開數據庫
	db, err := sql.Open("sqlite", dbPath)
	if err != nil {
		log.Fatalf("❌ 打開數據庫失敗: %v", err)
	}
	defer db.Close()

	// 4. 初始化加密管理器
	em, err := crypto.GetEncryptionManager()
	if err != nil {
		log.Fatalf("❌ 初始化加密管理器失敗: %v", err)
	}

	// 5. 遷移交易所配置
	if err := migrateExchanges(db, em); err != nil {
		log.Fatalf("❌ 遷移交易所配置失敗: %v", err)
	}

	// 6. 遷移 AI 模型配置
	if err := migrateAIModels(db, em); err != nil {
		log.Fatalf("❌ 遷移 AI 模型配置失敗: %v", err)
	}

	log.Println("✅ 數據遷移完成！")
	log.Printf("📝 原始數據備份位於: %s", backupPath)
	log.Println("⚠️  請驗證系統功能正常後，手動刪除備份檔案")
}

// migrateExchanges 遷移交易所配置
func migrateExchanges(db *sql.DB, em *crypto.EncryptionManager) error {
	log.Println("🔄 遷移交易所配置...")

	// 查詢所有未加密的記錄（假設加密數據都包含 '==' Base64 特徵）
	rows, err := db.Query(`
		SELECT user_id, id, api_key, secret_key,
		       COALESCE(hyperliquid_private_key, ''),
		       COALESCE(aster_private_key, '')
		FROM exchanges
		WHERE (api_key != '' AND api_key NOT LIKE '%==%')
		   OR (secret_key != '' AND secret_key NOT LIKE '%==%')
	`)
	if err != nil {
		return err
	}
	defer rows.Close()

	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	count := 0
	for rows.Next() {
		var userID, exchangeID, apiKey, secretKey, hlPrivateKey, asterPrivateKey string
		if err := rows.Scan(&userID, &exchangeID, &apiKey, &secretKey, &hlPrivateKey, &asterPrivateKey); err != nil {
			return err
		}

		// 加密每個字段
		encAPIKey, err := em.EncryptForDatabase(apiKey)
		if err != nil {
			return fmt.Errorf("加密 API Key 失敗: %w", err)
		}

		encSecretKey, err := em.EncryptForDatabase(secretKey)
		if err != nil {
			return fmt.Errorf("加密 Secret Key 失敗: %w", err)
		}

		encHLPrivateKey := ""
		if hlPrivateKey != "" {
			encHLPrivateKey, err = em.EncryptForDatabase(hlPrivateKey)
			if err != nil {
				return fmt.Errorf("加密 Hyperliquid Private Key 失敗: %w", err)
			}
		}

		encAsterPrivateKey := ""
		if asterPrivateKey != "" {
			encAsterPrivateKey, err = em.EncryptForDatabase(asterPrivateKey)
			if err != nil {
				return fmt.Errorf("加密 Aster Private Key 失敗: %w", err)
			}
		}

		// 更新數據庫
		_, err = tx.Exec(`
			UPDATE exchanges
			SET api_key = ?, secret_key = ?,
			    hyperliquid_private_key = ?, aster_private_key = ?
			WHERE user_id = ? AND id = ?
		`, encAPIKey, encSecretKey, encHLPrivateKey, encAsterPrivateKey, userID, exchangeID)

		if err != nil {
			return fmt.Errorf("更新數據庫失敗: %w", err)
		}

		log.Printf("  ✓ 已加密: [%s] %s", userID, exchangeID)
		count++
	}

	if err := tx.Commit(); err != nil {
		return err
	}

	log.Printf("✅ 已遷移 %d 個交易所配置", count)
	return nil
}

// migrateAIModels 遷移 AI 模型配置
func migrateAIModels(db *sql.DB, em *crypto.EncryptionManager) error {
	log.Println("🔄 遷移 AI 模型配置...")

	rows, err := db.Query(`
		SELECT user_id, id, api_key
		FROM ai_models
		WHERE api_key != '' AND api_key NOT LIKE '%==%'
	`)
	if err != nil {
		return err
	}
	defer rows.Close()

	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	count := 0
	for rows.Next() {
		var userID, modelID, apiKey string
		if err := rows.Scan(&userID, &modelID, &apiKey); err != nil {
			return err
		}

		encAPIKey, err := em.EncryptForDatabase(apiKey)
		if err != nil {
			return fmt.Errorf("加密 API Key 失敗: %w", err)
		}

		_, err = tx.Exec(`
			UPDATE ai_models SET api_key = ? WHERE user_id = ? AND id = ?
		`, encAPIKey, userID, modelID)

		if err != nil {
			return fmt.Errorf("更新數據庫失敗: %w", err)
		}

		log.Printf("  ✓ 已加密: [%s] %s", userID, modelID)
		count++
	}

	if err := tx.Commit(); err != nil {
		return err
	}

	log.Printf("✅ 已遷移 %d 個 AI 模型配置", count)
	return nil
}
