package main

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

	_ "github.com/jackc/pgx/v5/stdlib"
	"github.com/joho/godotenv"
)

func main() {
	fmt.Println("=== Database Connection Diagnostic Tool ===")
	
	// Load environment variables from .env file
	if err := godotenv.Load(); err != nil {
		log.Printf("Warning: Error loading .env file: %v", err)
	}
	
	// Get configuration from environment
	host := os.Getenv("DB_HOST")
	port := os.Getenv("DB_PORT")
	username := os.Getenv("DB_USERNAME")
	password := os.Getenv("DB_PASSWORD")
	database := os.Getenv("DB_DATABASE")
	sslmode := os.Getenv("DB_SSLMODE")
	
	if sslmode == "" {
		sslmode = "disable"
	}
	
	fmt.Printf("Host: %s\n", host)
	fmt.Printf("Port: %s\n", port)
	fmt.Printf("Username: %s\n", username)
	fmt.Printf("Database: %s\n", database)
	fmt.Printf("SSL Mode: %s\n", sslmode)
	
	if host == "" || username == "" || password == "" {
		fmt.Println("❌ Missing required environment variables")
		return
	}
	
	// Test connection to PostgreSQL server
	fmt.Println("\n--- Testing PostgreSQL Server Connection ---")
	serverConnStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=postgres sslmode=%s",
		host, port, username, password, sslmode)
	
	db, err := sql.Open("pgx", serverConnStr)
	if err != nil {
		fmt.Printf("❌ Failed to connect to PostgreSQL server: %v\n", err)
		return
	}
	defer db.Close()
	
	err = db.Ping()
	if err != nil {
		fmt.Printf("❌ Failed to ping PostgreSQL server: %v\n", err)
		return
	}
	
	fmt.Println("✅ Successfully connected to PostgreSQL server")
	
	// Check if database exists
	fmt.Println("\n--- Checking Database Existence ---")
	var exists bool
	err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = $1)", database).Scan(&exists)
	if err != nil {
		fmt.Printf("❌ Failed to check database existence: %v\n", err)
		return
	}
	
	if !exists {
		fmt.Printf("❌ Database '%s' does not exist\n", database)
		
		// List available databases
		fmt.Println("\n--- Available Databases ---")
		rows, err := db.Query("SELECT datname FROM pg_database WHERE datistemplate = false ORDER BY datname")
		if err != nil {
			fmt.Printf("❌ Failed to list databases: %v\n", err)
			return
		}
		defer rows.Close()
		
		fmt.Println("Available databases:")
		for rows.Next() {
			var dbName string
			if err := rows.Scan(&dbName); err != nil {
				continue
			}
			fmt.Printf("  - %s\n", dbName)
		}
		return
	}
	
	fmt.Printf("✅ Database '%s' exists\n", database)
	
	// Test direct connection to the database
	fmt.Println("\n--- Testing Direct Database Connection ---")
	directConnStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
		host, port, username, password, database, sslmode)
	
	targetDB, err := sql.Open("pgx", directConnStr)
	if err != nil {
		fmt.Printf("❌ Failed to connect to database '%s': %v\n", database, err)
		return
	}
	defer targetDB.Close()
	
	err = targetDB.Ping()
	if err != nil {
		fmt.Printf("❌ Failed to ping database '%s': %v\n", database, err)
		return
	}
	
	fmt.Printf("✅ Successfully connected to database '%s'\n", database)
	
	// Test basic query
	fmt.Println("\n--- Testing Basic Query ---")
	var version string
	err = targetDB.QueryRow("SELECT version()").Scan(&version)
	if err != nil {
		fmt.Printf("❌ Failed to execute query: %v\n", err)
		return
	}
	
	fmt.Printf("✅ PostgreSQL Version: %s\n", version)
	
	fmt.Println("\n🎉 All tests passed! Database connection is working correctly.")
}
