package tools

import (
	"context"
	"os"
	"path/filepath"
	"testing"

	"github.com/modelcontextprotocol/go-sdk/mcp"
)

func TestCreateOrUpdatePattern_CreateDuplicate(t *testing.T) {
	// Setup: Use test database
	testDB := filepath.Join("..", "db", "test.duckdb")
	if _, err := os.Stat(testDB); os.IsNotExist(err) {
		t.Skipf("Test database not found at %s", testDB)
	}
	SetDBPath(testDB)

	ctx := context.Background()

	// Test 1: Try to create duplicate of existing pattern (60s/1740s)
	// Should return existing pattern IBv_KxDGsNQs
	t.Run("CreateDuplicatePattern", func(t *testing.T) {
		record := 60
		sleep := 1740
		input := PatternInput{
			RecordSeconds: &record,
			SleepSeconds:  &sleep,
		}

		result, output, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
		if err != nil {
			t.Fatalf("Expected no error, got: %v", err)
		}
		if result == nil {
			t.Fatal("Expected non-nil result")
		}

		// Should return existing pattern
		if output.Pattern.ID != "IBv_KxDGsNQs" {
			t.Errorf("Expected existing pattern ID 'IBv_KxDGsNQs', got '%s'", output.Pattern.ID)
		}

		if output.Pattern.RecordS != 60 {
			t.Errorf("Expected record_s 60, got %d", output.Pattern.RecordS)
		}
		if output.Pattern.SleepS != 1740 {
			t.Errorf("Expected sleep_s 1740, got %d", output.Pattern.SleepS)
		}

		// Check message indicates existing pattern
		if output.Message == "" {
			t.Error("Expected non-empty message")
		}
		t.Logf("Message: %s", output.Message)
	})

	// Test 2: Create new unique pattern
	t.Run("CreateUniquePattern", func(t *testing.T) {
		record := 999
		sleep := 888
		input := PatternInput{
			RecordSeconds: &record,
			SleepSeconds:  &sleep,
		}

		result, output, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
		if err != nil {
			t.Fatalf("Expected no error, got: %v", err)
		}
		if result == nil {
			t.Fatal("Expected non-nil result")
		}

		// Should create new pattern
		firstID := output.Pattern.ID
		if firstID == "" {
			t.Fatal("Expected non-empty ID")
		}
		if output.Pattern.RecordS != 999 {
			t.Errorf("Expected record_s 999, got %d", output.Pattern.RecordS)
		}
		if output.Pattern.SleepS != 888 {
			t.Errorf("Expected sleep_s 888, got %d", output.Pattern.SleepS)
		}
		t.Logf("Created pattern ID: %s", firstID)

		// Test 3: Try to create duplicate of the pattern we just created (idempotent)
		result2, output2, err2 := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
		if err2 != nil {
			t.Fatalf("Expected no error on duplicate, got: %v", err2)
		}
		if result2 == nil {
			t.Fatal("Expected non-nil result")
		}

		// Should return same pattern
		if output2.Pattern.ID != firstID {
			t.Errorf("Expected same pattern ID '%s', got '%s'", firstID, output2.Pattern.ID)
		}
		t.Logf("Idempotent test passed - returned same ID: %s", output2.Pattern.ID)
	})
}

func TestCreateOrUpdatePattern_Validation(t *testing.T) {
	testDB := filepath.Join("..", "db", "test.duckdb")
	if _, err := os.Stat(testDB); os.IsNotExist(err) {
		t.Skipf("Test database not found at %s", testDB)
	}
	SetDBPath(testDB)

	ctx := context.Background()

	// Test invalid inputs for create (no ID = create mode)
	tests := []struct {
		name          string
		recordSeconds int
		sleepSeconds  int
		wantError     bool
	}{
		{"ZeroRecordSeconds", 0, 100, true},
		{"NegativeRecordSeconds", -10, 100, true},
		{"ZeroSleepSeconds", 100, 0, true},
		{"NegativeSleepSeconds", 100, -10, true},
		{"ValidInputs", 10, 20, false},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			input := PatternInput{
				RecordSeconds: &tt.recordSeconds,
				SleepSeconds:  &tt.sleepSeconds,
			}

			_, _, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
			if (err != nil) != tt.wantError {
				t.Errorf("Expected error=%v, got error=%v", tt.wantError, err != nil)
			}
		})
	}
}

func TestCreateOrUpdatePattern_Update(t *testing.T) {
	testDB := filepath.Join("..", "db", "test.duckdb")
	if _, err := os.Stat(testDB); os.IsNotExist(err) {
		t.Skipf("Test database not found at %s", testDB)
	}
	SetDBPath(testDB)

	ctx := context.Background()

	t.Run("UpdateNonExistentPattern", func(t *testing.T) {
		id := "NONEXISTENT1"
		record := 100
		input := PatternInput{
			ID:            &id,
			RecordSeconds: &record,
		}

		_, _, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
		if err == nil {
			t.Error("Expected error for non-existent pattern")
		}
	})

	t.Run("UpdateNoFields", func(t *testing.T) {
		id := "IBv_KxDGsNQs"
		input := PatternInput{
			ID: &id,
		}

		_, _, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
		if err == nil {
			t.Error("Expected error when no fields provided")
		}
	})
}