package infra

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestMigrationCreate(t *testing.T) {
	t.Run("directorio vacio crea archivo con version 001", func(t *testing.T) {
		dir := t.TempDir()
		path, err := MigrationCreate(dir, "create_users")
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		base := filepath.Base(path)
		if base != "001_create_users.sql" {
			t.Errorf("filename: got %q, want %q", base, "001_create_users.sql")
		}

		content, err := os.ReadFile(path)
		if err != nil {
			t.Fatalf("cannot read created file: %v", err)
		}
		if !strings.Contains(string(content), "-- +up") {
			t.Errorf("file missing -- +up marker")
		}
		if !strings.Contains(string(content), "-- +down") {
			t.Errorf("file missing -- +down marker")
		}
	})

	t.Run("directorio con migraciones existentes calcula siguiente version", func(t *testing.T) {
		dir := t.TempDir()

		// Create existing files
		os.WriteFile(filepath.Join(dir, "001_create_users.sql"), []byte("-- +up\nCREATE TABLE users (id TEXT);\n-- +down\nDROP TABLE users;\n"), 0o644)
		os.WriteFile(filepath.Join(dir, "002_add_email.sql"), []byte("-- +up\nALTER TABLE users ADD COLUMN email TEXT;\n-- +down\n\n"), 0o644)

		path, err := MigrationCreate(dir, "add_index")
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		base := filepath.Base(path)
		if base != "003_add_index.sql" {
			t.Errorf("filename: got %q, want %q", base, "003_add_index.sql")
		}
	})

	t.Run("nombre invalido retorna error", func(t *testing.T) {
		dir := t.TempDir()
		_, err := MigrationCreate(dir, "123invalid")
		if err == nil {
			t.Fatal("expected error for invalid name, got nil")
		}
	})

	t.Run("directorio inexistente se crea automaticamente", func(t *testing.T) {
		base := t.TempDir()
		dir := filepath.Join(base, "nested", "migrations")

		path, err := MigrationCreate(dir, "init")
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		if _, err := os.Stat(dir); os.IsNotExist(err) {
			t.Errorf("directory was not created: %s", dir)
		}

		if filepath.Dir(path) != dir {
			t.Errorf("file not in expected dir: %s", path)
		}
	})
}
