package main

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

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	if len(os.Args) < 2 {
		printUsage()
		os.Exit(1)
	}

	command := os.Args[1]

	// Database file path
	dbPath := "./butterfliu.db"
	if len(os.Args) > 3 && os.Args[1] == "db" {
		dbPath = os.Args[3]
	}

	log.Printf("Using database: %s", dbPath)

	// Open database connection
	db, err := sql.Open("sqlite3", dbPath)
	if err != nil {
		log.Fatalf("Error opening database %s: %v", dbPath, err)
	}
	defer db.Close()

	// Test connection
	if err = db.Ping(); err != nil {
		log.Fatalf("Error connecting to database %s: %v", dbPath, err)
	}

	// Initialize migration table
	if err = migrations.InitMigrationTable(db); err != nil {
		log.Fatalf("Error initializing migration table: %v", err)
	}

	switch command {
	case "up":
		// Run all pending migrations
		if err := migrations.MigrateUp(db); err != nil {
			log.Fatalf("Error applying migrations: %v", err)
		}
		log.Println("All migrations applied successfully")

	case "down":
		if len(os.Args) < 3 {
			log.Println("Error: Missing target version")
			printUsage()
			os.Exit(1)
		}

		targetVersion, err := parseVersion(os.Args[2])
		if err != nil {
			log.Fatalf("Error parsing target version: %v", err)
		}

		// Roll back migrations to target version
		if err := migrations.MigrateDown(db, targetVersion); err != nil {
			log.Fatalf("Error rolling back migrations: %v", err)
		}
		log.Printf("Migrations rolled back to version %d successfully\n", targetVersion)

	case "reset":
		// Roll back all migrations
		if err := migrations.MigrateDown(db, 0); err != nil {
			log.Fatalf("Error rolling back migrations: %v", err)
		}
		log.Println("All migrations rolled back successfully")

	case "refresh":
		// Roll back all migrations and then apply them again
		if err := migrations.MigrateDown(db, 0); err != nil {
			log.Fatalf("Error rolling back migrations: %v", err)
		}
		if err := migrations.MigrateUp(db); err != nil {
			log.Fatalf("Error applying migrations: %v", err)
		}
		log.Println("All migrations refreshed successfully")

	case "status":
		// Show migration status
		migrationList, err := migrations.ListMigrations(db)
		if err != nil {
			log.Fatalf("Error listing migrations: %v", err)
		}

		log.Println("Migration Status:")
		log.Println("=================")
		for _, migration := range migrationList {
			status := "Pending"
			appliedAt := ""
			if applied, ok := migration["applied"].(bool); ok && applied {
				status = "Applied"
				appliedAt = migration["applied_at"].(string)
			}
			log.Printf("%d: %s - %s %s\n", migration["version"], migration["description"], status, appliedAt)
		}

	case "create":
		if len(os.Args) < 3 {
			log.Println("Error: Missing migration name")
			printUsage()
			os.Exit(1)
		}

		name := os.Args[2]
		if err := migrations.CreateMigration(name); err != nil {
			log.Fatalf("Error creating migration: %v", err)
		}

	default:
		log.Printf("Error: Unknown command '%s'\n", command)
		printUsage()
		os.Exit(1)
	}
}

func printUsage() {
	log.Println("Usage: go run cmd/migrate/main.go <command> [args]")
	log.Println("")
	log.Println("Commands:")
	log.Println("  up                   Apply all pending migrations")
	log.Println("  down <version>       Roll back migrations to specified version")
	log.Println("  reset                Roll back all migrations")
	log.Println("  refresh              Roll back all migrations and apply them again")
	log.Println("  status               Show migration status")
	log.Println("  create <name>        Create a new migration")
}

func parseVersion(s string) (int, error) {
	var v int
	_, err := fmt.Sscanf(s, "%d", &v)
	return v, err
}
