// +build integration

package tests

import (
	"context"
	"os"
	"testing"
	"time"

	"github.com/rockliang/poimen/workflows/internal/routing"
	"github.com/rockliang/poimen/workflows/statemachine"
	"github.com/stretchr/testify/require"
	"go.temporal.io/sdk/client"
)

// TestTemporalRoutingWorkflow tests full flow against real Temporal cluster
// Run with: TEMPORAL_HOSTPORT=temporal.riotpiao.com:7233 RUN_INTEGRATION_TESTS=1 go test -tags=integration -v -run TestTemporalRoutingWorkflow ./tests/...
func TestTemporalRoutingWorkflow(t *testing.T) {
	if os.Getenv("RUN_INTEGRATION_TESTS") != "1" {
		t.Skip("Skipping integration test. Set RUN_INTEGRATION_TESTS=1 to run.")
	}

	hostPort := os.Getenv("TEMPORAL_HOSTPORT")
	if hostPort == "" {
		hostPort = "temporal.riotpiao.com:7233"
	}

	namespace := os.Getenv("TEMPORAL_NAMESPACE")
	if namespace == "" {
		namespace = "poimen-harness"
	}

	t.Logf("Connecting to Temporal at %s (namespace: %s)", hostPort, namespace)

	// Connect to Temporal
	c, err := client.Dial(client.Options{
		HostPort:  hostPort,
		Namespace: namespace,
	})
	if err != nil {
		t.Skipf("Skipping - cannot connect to Temporal: %v", err)
	}
	defer c.Close()

	t.Log("Connected to Temporal successfully")

	// Test 1: Generate spec via LLM and submit
	t.Run("LLM_Route_And_Submit", func(t *testing.T) {
		// Load KB and create router
		kb, err := routing.LoadKnowledgeBaseFromDefaultPath()
		require.NoError(t, err)

		router, err := routing.NewLLMRouter(kb)
		require.NoError(t, err)

		// Generate workflow spec
		ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
		defer cancel()

		output, err := router.Route(ctx, routing.LLMRouterInput{
			Message: "Clone and analyze https://github.com/rockliang/poimen",
		})
		require.NoError(t, err)
		require.False(t, output.IsCron)
		require.NotNil(t, output.Spec)

		t.Logf("Generated spec: %s with %d states", output.Spec.Name, len(output.Spec.States))

		// Submit to Temporal
		workflowID := "test-routing-" + time.Now().Format("20060102-150405")
		input := statemachine.RoutingWorkflowInput{Spec: output.Spec}

		run, err := c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
			ID:        workflowID,
			TaskQueue: "poimen-taskqueue",
		}, statemachine.RoutingWorkflow, input)
		require.NoError(t, err)

		t.Logf("Workflow submitted: ID=%s, RunID=%s", run.GetID(), run.GetRunID())

		// Check workflow started (don't wait for completion - activities may not be registered)
		desc, err := c.DescribeWorkflowExecution(ctx, workflowID, "")
		require.NoError(t, err)
		t.Logf("Workflow status: %s", desc.WorkflowExecutionInfo.Status.String())

		// Cancel the workflow (since activities may not be running)
		err = c.CancelWorkflow(ctx, workflowID, "")
		if err != nil {
			t.Logf("Cancel failed (may already be done): %v", err)
		} else {
			t.Log("Workflow cancelled")
		}
	})

	// Test 2: Submit simple Pass-only workflow (no activities needed)
	t.Run("PassOnly_Workflow", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
		defer cancel()

		spec := &routing.WorkflowSpec{
			Name:  "pass-only-test",
			Input: map[string]interface{}{"test": true},
			States: []routing.State{
				{
					Name:   "Step1",
					Type:   routing.StateTypePass,
					Result: map[string]interface{}{"status": "step1-done"},
					Next:   "Step2",
				},
				{
					Name:   "Step2",
					Type:   routing.StateTypePass,
					Result: map[string]interface{}{"status": "step2-done", "final": true},
					End:    true,
				},
			},
		}

		workflowID := "test-pass-only-" + time.Now().Format("20060102-150405")
		input := statemachine.RoutingWorkflowInput{Spec: spec}

		run, err := c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
			ID:        workflowID,
			TaskQueue: "poimen-taskqueue",
		}, statemachine.RoutingWorkflow, input)
		require.NoError(t, err)

		t.Logf("Pass-only workflow submitted: ID=%s", run.GetID())

		// Wait for result (Pass states don't need workers)
		var result statemachine.RoutingWorkflowOutput
		err = run.Get(ctx, &result)
		require.NoError(t, err)

		t.Logf("Workflow result: status=%s", result.Status)
		require.Equal(t, "COMPLETED", result.Status)
		require.Contains(t, result.StepResults, "Step1")
		require.Contains(t, result.StepResults, "Step2")
	})
}
