package database

import (
	"database/sql"
	"fmt"
	"log"
	"studia/internal/config"
	"studia/internal/logger"

	_ "github.com/lib/pq" // Import the PostgreSQL driver
)

var expectedTables = []string{
	"users",
}

func New(cfg *config.Config) *sql.DB {
	db := setupDatabase(cfg)

	existing, err := getExistingTables(db, `
		SELECT table_name
		FROM information_schema.tables
		WHERE table_schema = 'public'
	`)
	if err != nil {
		logger.Log.Error().Err(err).Msg("Failed to query existing tables")
	}

	missing := checkTables(expectedTables, existing)

	if len(missing) > 0 {
		log.Println("Missing tables detected:", missing)
		// Here you would normally run migrations to create the missing tables
		// For simplicity, we just log the missing tables
	} else {
		logger.Log.Info().Msg("All expected tables are present.")
	}

	return db
}

func setupDatabase(cfg *config.Config) *sql.DB {
	// Database connection setup logic here

	logger.Log.Println(cfg)
	switch cfg.DatabaseDriver {
	case "postgres":
		// Setup Postgres connection
		log.Println("Setting up Postgres connection")
		psqlInfo := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
			cfg.DatabaseHost, cfg.DatabasePort, cfg.DatabaseUser, cfg.DatabasePassword, cfg.DatabaseName)
		db, err := sql.Open("postgres", psqlInfo)
		if err != nil {
			log.Fatal("Failed to connect to database:", err)
		}
		return db
	case "mysql":
		// Setup MySQL connection
		dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",
			cfg.DatabaseUser, cfg.DatabasePassword, cfg.DatabaseHost, cfg.DatabasePort, cfg.DatabaseName)
		db, err := sql.Open("mysql", dsn)
		if err != nil {
			// Handle error
		}
		return db
	default:
		// Handle unsupported database driver
	}
	return nil
}

func getExistingTables(db *sql.DB, query string) (map[string]bool, error) {
	rows, err := db.Query(query)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	tables := make(map[string]bool)
	for rows.Next() {
		var name string
		if err := rows.Scan(&name); err != nil {
			return nil, err
		}
		tables[name] = true
	}
	return tables, nil
}

func checkTables(expected []string, existing map[string]bool) []string {
	var missing []string
	for _, table := range expected {
		if !existing[table] {
			missing = append(missing, table)
		}
	}
	return missing
}
