package adk_test

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/orchard9/stemedb-go/adk"
	"github.com/orchard9/stemedb-go/steme"
)

// Example showing basic tool usage
func ExampleQueryTool() {
	// Create client (in production, use real endpoint)
	signer, err := steme.GenerateSigner()
	if err != nil {
		log.Fatalf("Failed to generate signer: %v", err)
	}
	client := steme.NewClient("http://localhost:18180", signer)

	// Create query tool
	tool := adk.NewQueryTool(client)

	// Prepare input
	input := adk.QueryInput{
		Subject:   "Tesla_Inc",
		Predicate: "has_revenue",
		Lens:      "consensus",
		Lifecycle: "approved",
	}

	inputBytes, err := json.Marshal(input)
	if err != nil {
		log.Fatalf("Failed to marshal input: %v", err)
	}

	// Execute query (note: this will fail without a running server)
	outputBytes, err := tool.Execute(context.Background(), inputBytes)
	if err != nil {
		log.Printf("Query failed: %v", err)
		return
	}

	var output adk.QueryOutput
	if err := json.Unmarshal(outputBytes, &output); err != nil {
		log.Fatalf("Failed to unmarshal output: %v", err)
	}

	fmt.Printf("Value: %v, Confidence: %.2f\n", output.Value, output.Confidence)
}

// Example showing implementation agent configuration
func ExampleConfigForImplementationAgent() {
	signer, err := steme.GenerateSigner()
	if err != nil {
		log.Fatalf("Failed to generate signer: %v", err)
	}
	client := steme.NewClient("http://localhost:18180", signer)

	// Configure implementation agent
	config := adk.ConfigForImplementationAgent(client, log.Printf)

	fmt.Println(config.Name)
	fmt.Println(len(config.Tools) >= 2) // Has at least query and constraint check

	// Output:
	// implementation_agent
	// true
}

// Example showing all tools
func ExampleAllTools() {
	signer, _ := steme.GenerateSigner()
	client := steme.NewClient("http://localhost:18180", signer)

	tools := adk.AllTools(client)

	for _, tool := range tools {
		fmt.Println(tool.Name())
	}

	// Output:
	// episteme_query
	// episteme_assert
	// episteme_constraint_check
	// episteme_trace
	// episteme_supersede
}

// Example showing multi-agent configuration
func ExampleAllConfigs() {
	signer, _ := steme.GenerateSigner()
	client := steme.NewClient("http://localhost:18180", signer)

	sessionState := make(map[string]any)
	setState := func(key string, value any) {
		sessionState[key] = value
	}

	configs := adk.AllConfigs(client, 0.8, setState, log.Printf)

	// Show available agent types
	for agentType := range configs {
		fmt.Println(agentType)
	}

	// Output (order may vary):
	// implementation
	// lead
	// oncall
	// research
	// supervisor
}

// Example showing constraint enforcement callback
func ExampleConstraintEnforcementCallback() {
	signer, _ := steme.GenerateSigner()
	client := steme.NewClient("http://localhost:18180", signer)

	// Define which tools require constraint checking
	codeGenTools := []string{"write_code", "generate_config"}

	// Create callback
	callback := adk.ConstraintEnforcementCallback(client, codeGenTools)

	// Use in agent configuration
	_ = callback // In practice: agent.BeforeToolCallback = callback

	fmt.Println("Constraint enforcement callback created")

	// Output:
	// Constraint enforcement callback created
}

// Example showing confidence escalation callback
func ExampleConfidenceEscalationCallback() {
	sessionState := make(map[string]any)
	setState := func(key string, value any) {
		sessionState[key] = value
	}

	// Create callback with 0.8 threshold
	callback := adk.ConfidenceEscalationCallback(0.8, setState)

	// Use in agent configuration
	_ = callback // In practice: agent.AfterToolCallback = callback

	fmt.Println("Confidence escalation callback created")

	// Output:
	// Confidence escalation callback created
}

// Example showing callback chaining
func ExampleChainAfterCallbacks() {
	sessionState := make(map[string]any)
	setState := func(key string, value any) {
		sessionState[key] = value
	}

	// Chain multiple callbacks
	callback := adk.ChainAfterCallbacks(
		adk.ConfidenceEscalationCallback(0.8, setState),
		adk.AuditLoggingCallback(log.Printf),
	)

	// Use in agent configuration
	_ = callback // In practice: agent.AfterToolCallback = callback

	fmt.Println("Chained callbacks created")

	// Output:
	// Chained callbacks created
}
