package tools

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

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

func TestPatternIntegration_CreateClusterWithExistingPattern(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()

	// First, verify we can query existing patterns
	t.Run("QueryExistingPatterns", func(t *testing.T) {
		input := ExecuteSQLInput{
			Query: "SELECT id, record_s, sleep_s FROM cyclic_recording_pattern WHERE active = true ORDER BY record_s, sleep_s",
		}

		result, output, err := ExecuteSQL(ctx, &mcp.CallToolRequest{}, input)
		if err != nil {
			t.Fatalf("Failed to query patterns: %v", err)
		}
		if result == nil {
			t.Fatal("Expected non-nil result")
		}

		if len(output.Rows) == 0 {
			t.Fatal("Expected at least one pattern")
		}

		t.Logf("Found %d patterns", len(output.Rows))
		for i, row := range output.Rows {
			t.Logf("Pattern %d: ID=%v, record_s=%v, sleep_s=%v", i+1, row["id"], row["record_s"], row["sleep_s"])
		}
	})

	// Create a cluster using an existing pattern
	t.Run("CreateClusterWithExistingPattern", func(t *testing.T) {
		// First, find a valid dataset and location
		datasetSQL := ExecuteSQLInput{
			Query: "SELECT id FROM dataset WHERE active = true LIMIT 1",
		}
		_, datasetOutput, err := ExecuteSQL(ctx, &mcp.CallToolRequest{}, datasetSQL)
		if err != nil || len(datasetOutput.Rows) == 0 {
			t.Skip("No active datasets found in test database")
		}
		datasetID := datasetOutput.Rows[0]["id"].(string)

		locationSQL := ExecuteSQLInput{
			Query:      "SELECT id FROM location WHERE dataset_id = ? AND active = true LIMIT 1",
			Parameters: []interface{}{datasetID},
		}
		_, locationOutput, err := ExecuteSQL(ctx, &mcp.CallToolRequest{}, locationSQL)
		if err != nil || len(locationOutput.Rows) == 0 {
			t.Skip("No active locations found in test database")
		}
		locationID := locationOutput.Rows[0]["id"].(string)

		t.Logf("Using dataset: %s, location: %s", datasetID, locationID)

		sampleRate := 16000
		input := ClusterInput{
			DatasetID:                &datasetID,
			LocationID:               &locationID,
			Name:                     stringPtr("Integration Test Cluster"),
			SampleRate:               &sampleRate,
			CyclicRecordingPatternID: stringPtr("IBv_KxDGsNQs"), // 60s/1740s pattern
		}

		result, output, err := CreateOrUpdateCluster(ctx, &mcp.CallToolRequest{}, input)
		if err != nil {
			t.Fatalf("Failed to create cluster: %v", err)
		}
		if result == nil {
			t.Fatal("Expected non-nil result")
		}

		clusterID := output.Cluster.ID
		t.Logf("Created cluster: %s with pattern reference", clusterID)

		// Verify the cluster has the pattern reference
		sqlInput := ExecuteSQLInput{
			Query: "SELECT c.name, c.cyclic_recording_pattern_id, p.record_s, p.sleep_s FROM cluster c LEFT JOIN cyclic_recording_pattern p ON c.cyclic_recording_pattern_id = p.id WHERE c.id = ?",
			Parameters: []interface{}{clusterID},
		}

		sqlResult, sqlOutput, err := ExecuteSQL(ctx, &mcp.CallToolRequest{}, sqlInput)
		if err != nil {
			t.Fatalf("Failed to verify cluster: %v", err)
		}
		if sqlResult == nil {
			t.Fatal("Expected non-nil result")
		}

		if len(sqlOutput.Rows) != 1 {
			t.Fatalf("Expected 1 row, got %d", len(sqlOutput.Rows))
		}

		row := sqlOutput.Rows[0]

		t.Logf("Row data: %+v", row)

		// SQL tool returns all values as strings, interface{}, or native types depending on DuckDB driver
		// Check the pattern ID
		patternIDStr := row["cyclic_recording_pattern_id"]
		if patternIDStr != "IBv_KxDGsNQs" {
			t.Errorf("Expected pattern ID 'IBv_KxDGsNQs', got '%v'", patternIDStr)
		}

		// Check record_s and sleep_s (can be string or int types)
		recordSVal := row["record_s"]
		sleepSVal := row["sleep_s"]

		t.Logf("✓ Verified cluster has correct pattern reference: ID=%v, record=%v, sleep=%v",
			patternIDStr, recordSVal, sleepSVal)

		// Just verify they're not nil/empty
		if patternIDStr == nil || patternIDStr == "" {
			t.Error("Pattern ID is empty")
		}
		if recordSVal == nil {
			t.Error("record_s is nil")
		}
		if sleepSVal == nil {
			t.Error("sleep_s is nil")
		}
	})
}

func stringPtr(s string) *string {
	return &s
}