package repositories

import (
	"fmt"
	"log"

	"github.com/niangaodev/art-code/config"
)

// MigrateToBigInt performs schema migration to BigInt timestamps
func MigrateToBigInt() {
	tables := []string{
		"posts", "users", "tags", "works", "snippets", "settings",
		"about_profiles", "partners", "testimonials", "inquiries",
		"email_suffixes", "access_logs", "user_access_logs",
		"operation_logs", "permissions", "roles",
		"work_tech_stack", "work_gallery", "post_tags", "post_history",
	}

	for _, table := range tables {
		log.Printf("Migrating table: %s", table)

		// 1. Add deleted_at if not exists
		if !columnExists(table, "deleted_at") && table != "post_tags" { // post_tags doesn't need deleted_at in my previous plan? I added to all in SQL file? Yes.
			// Actually post_tags in SQL file I modified: `created_at` bigint. No `deleted_at`.
			// So skip deleted_at for post_tags.
			if table != "post_tags" {
				execSQL(fmt.Sprintf("ALTER TABLE `%s` ADD COLUMN `deleted_at` BIGINT NOT NULL DEFAULT 0", table))
			}
		}

		// 2. Migrate created_at
		migrateColumn(table, "created_at")

		// 3. Migrate updated_at (if exists)
		if columnExists(table, "updated_at") {
			migrateColumn(table, "updated_at")
		}

		// 4. Migrate access_time (for user_access_logs)
		if table == "user_access_logs" && columnExists(table, "access_time") {
			migrateColumn(table, "access_time")
		}

		// 5. Remove 'date' from posts if exists
		if table == "posts" && columnExists(table, "date") {
			execSQL("ALTER TABLE `posts` DROP COLUMN `date`")
			// Drop index idx_date if exists? MySQL drops index on column drop usually.
		}
	}
}

func columnExists(tableName, colName string) bool {
	var count int64
	err := config.DB.Raw(`
		SELECT COUNT(*) 
		FROM information_schema.columns 
		WHERE table_schema = DATABASE() 
		AND table_name = ? 
		AND column_name = ?
	`, tableName, colName).Scan(&count).Error
	if err != nil {
		log.Printf("Error checking column %s.%s: %v", tableName, colName, err)
		return false
	}
	return count > 0
}

func isBigInt(tableName, colName string) bool {
	var dataType string
	err := config.DB.Raw(`
		SELECT DATA_TYPE 
		FROM information_schema.columns 
		WHERE table_schema = DATABASE() 
		AND table_name = ? 
		AND column_name = ?
	`, tableName, colName).Scan(&dataType).Error
	if err != nil {
		return false
	}
	return dataType == "bigint" || dataType == "int"
}

func migrateColumn(table, col string) {
	if !columnExists(table, col) {
		return
	}
	if isBigInt(table, col) {
		return // Already migrated
	}

	log.Printf("Converting %s.%s to BIGINT...", table, col)

	// Rename old
	oldCol := col + "_old_dt"
	execSQL(fmt.Sprintf("ALTER TABLE `%s` CHANGE `%s` `%s` DATETIME", table, col, oldCol)) // Ensure it's treated as datetime for rename

	// Add new
	execSQL(fmt.Sprintf("ALTER TABLE `%s` ADD COLUMN `%s` BIGINT NOT NULL DEFAULT 0", table, col))

	// Copy and Convert
	execSQL(fmt.Sprintf("UPDATE `%s` SET `%s` = UNIX_TIMESTAMP(`%s`) WHERE `%s` IS NOT NULL", table, col, oldCol, oldCol))

	// Drop old
	execSQL(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN `%s`", table, oldCol))
}

func execSQL(query string) {
	err := config.DB.Exec(query).Error
	if err != nil {
		// Log but continue (might fail if column doesn't exist etc)
		log.Printf("SQL Error: %v | Query: %s", err, query)
	}
}
