package memory

import (
	"fmt"

	"go.temporal.io/sdk/workflow"
)

// LearningWorkflow learns from task execution
// Pattern: Execute → Learn → Document
func LearningWorkflow(ctx workflow.Context, taskID string, executor string) (string, error) {
	// Execute task (placeholder - replace with actual activity)
	taskResult := fmt.Sprintf("Task %s executed by %s", taskID, executor)

	// Learn from execution
	knowledgeID, err := ExecuteLearnFromExecution(
		ctx,
		taskID,
		taskResult,
		[]string{"execution", "learning"},
		DefaultActivityOptions(),
	)
	if err != nil {
		return "", fmt.Errorf("learn from execution: %w", err)
	}

	return knowledgeID, nil
}

// DiagnosticWorkflow diagnoses issue using memory service
// Pattern: Get Context → Extract Recommendations → Apply
func DiagnosticWorkflow(ctx workflow.Context, tool, issue string) ([]string, error) {
	// Get recommendations
	recommendations, err := ExecuteDiagnoseIssue(
		ctx,
		tool,
		issue,
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("diagnose: %w", err)
	}

	return recommendations, nil
}

// SearchAndApplyWorkflow searches knowledge and applies it
// Pattern: Search → Filter → Apply
func SearchAndApplyWorkflow(ctx workflow.Context, query string) ([]KnowledgeRecord, error) {
	// Search knowledge
	records, err := ExecuteSearchKnowledge(
		ctx,
		query,
		&RetrievalOptions{
			Limit:       10,
			LevelFilter: []string{"L1", "L2"},
			Floor:       0.7,
		},
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("search: %w", err)
	}

	return records, nil
}

// ContextualDecisionWorkflow makes decisions with memory context
// Pattern: Get Context → Make Decision → Document Decision
func ContextualDecisionWorkflow(ctx workflow.Context, tool, task string, decision string) (string, error) {
	// Get context
	svcCtx, err := ExecuteGetContext(
		ctx,
		tool,
		task,
		8192,
		DefaultActivityOptions(),
	)
	if err != nil {
		return "", fmt.Errorf("get context: %w", err)
	}

	// Build reasoning from lessons
	reasoning := fmt.Sprintf("Based on %d lessons from memory service (tier %d)", len(svcCtx.Lessons), svcCtx.Tier)

	// Document decision
	docID, err := ExecuteDocumentDecision(
		ctx,
		tool,
		decision,
		reasoning,
		DefaultActivityOptions(),
	)
	if err != nil {
		return "", fmt.Errorf("document decision: %w", err)
	}

	return docID, nil
}

// ErrorRecoveryWorkflow analyzes error and searches for recovery
// Pattern: Error → Analyze → Search → Recover
func ErrorRecoveryWorkflow(ctx workflow.Context, errorMsg string) ([]string, error) {
	// Analyze error
	records, err := ExecuteAnalyzeError(
		ctx,
		errorMsg,
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("analyze error: %w", err)
	}

	// Extract recovery recommendations
	recommendations := make([]string, 0)
	for _, record := range records {
		if record.Level == "L1" { // High confidence
			recommendations = append(recommendations, record.Content)
		}
	}

	return recommendations, nil
}

// HealthAwareWorkflow checks health before proceeding
// Pattern: HealthCheck → Conditional Proceed
func HealthAwareWorkflow(ctx workflow.Context, taskID string) (bool, error) {
	// Check health
	healthy, err := ExecuteHealthCheck(ctx, DefaultActivityOptions())
	if err != nil {
		return false, fmt.Errorf("health check: %w", err)
	}

	if !healthy {
		return false, fmt.Errorf("memory service unhealthy, skipping task %s", taskID)
	}

	return true, nil
}

// IterativeLearnWorkflow learns iteratively
// Pattern: Execute → Learn → Refine → Learn Again
func IterativeLearnWorkflow(ctx workflow.Context, topic string, iterations int) ([]string, error) {
	knowledgeIDs := make([]string, 0)

	for i := 0; i < iterations; i++ {
		// Learn current iteration
		id, err := ExecuteLearnFromExecution(
			ctx,
			fmt.Sprintf("%s-iteration-%d", topic, i+1),
			fmt.Sprintf("Iteration %d: %s", i+1, topic),
			[]string{"iteration", fmt.Sprintf("iteration-%d", i+1)},
			DefaultActivityOptions(),
		)
		if err != nil {
			return nil, fmt.Errorf("learn iteration %d: %w", i+1, err)
		}

		knowledgeIDs = append(knowledgeIDs, id)

		// Search for related knowledge
		records, err := ExecuteSearchKnowledge(
			ctx,
			topic,
			&RetrievalOptions{Limit: 5, Floor: 0.6},
			DefaultActivityOptions(),
		)
		if err != nil {
			return nil, fmt.Errorf("search iteration %d: %w", i+1, err)
		}

		// Log found records
		if len(records) > 0 {
			workflow.GetLogger(ctx).Info("Iteration found related records", "iteration", i+1, "records", len(records))
		}
	}

	return knowledgeIDs, nil
}

// ConditionalLearningWorkflow learns only on success
// Pattern: Execute → If Success → Learn
func ConditionalLearningWorkflow(ctx workflow.Context, taskID string, shouldSucceed bool) (string, error) {
	if !shouldSucceed {
		return "", fmt.Errorf("task failed, skipping learning")
	}

	// Only learn on success
	result := fmt.Sprintf("Task %s succeeded", taskID)

	id, err := ExecuteLearnFromExecution(
		ctx,
		taskID,
		result,
		[]string{"success"},
		DefaultActivityOptions(),
	)
	if err != nil {
		return "", fmt.Errorf("learn from success: %w", err)
	}

	return id, nil
}

// MultiStepWorkflow performs multiple memory operations
// Pattern: Create → Search → Context → Document
func MultiStepWorkflow(ctx workflow.Context, topic string) (map[string]interface{}, error) {
	results := make(map[string]interface{})

	// Step 1: Create knowledge
	createID, err := ExecuteCreateKnowledge(
		ctx,
		&KnowledgeRecord{
			Level:   "L1",
			Title:   fmt.Sprintf("Initial: %s", topic),
			Content: fmt.Sprintf("Starting workflow for %s", topic),
			Source:  "workflow://multi-step",
		},
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("create knowledge: %w", err)
	}
	results["created"] = createID

	// Step 2: Search knowledge
	searchRecords, err := ExecuteSearchKnowledge(
		ctx,
		topic,
		&RetrievalOptions{Limit: 5},
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("search knowledge: %w", err)
	}
	results["found"] = len(searchRecords)

	// Step 3: Get context
	svcCtx, err := ExecuteGetContext(
		ctx,
		"workflow",
		topic,
		8192,
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("get context: %w", err)
	}
	results["context_tier"] = svcCtx.Tier
	results["lessons"] = len(svcCtx.Lessons)
	results["skills"] = len(svcCtx.Skills)

	// Step 4: Document completion
	docID, err := ExecuteDocumentDecision(
		ctx,
		"workflow_completion",
		fmt.Sprintf("Completed multi-step workflow for %s", topic),
		fmt.Sprintf("Found %d records, tier %d context", len(searchRecords), svcCtx.Tier),
		DefaultActivityOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("document completion: %w", err)
	}
	results["documented"] = docID

	return results, nil
}

// ParallelLearnWorkflow learns from multiple sources in parallel
// Pattern: Execute Multiple Tasks in Parallel → Learn from Each
func ParallelLearnWorkflow(ctx workflow.Context, taskIDs []string) ([]string, error) {
	// Create parallel activities
	futures := make([]workflow.Future, len(taskIDs))

	for i, taskID := range taskIDs {
		// Execute each task in parallel
		future := workflow.ExecuteActivity(
			workflow.WithActivityOptions(
				ctx,
				workflow.ActivityOptions{
					ScheduleToCloseTimeout: DefaultActivityOptions().RetryBackoff * 60,
					StartToCloseTimeout:    DefaultActivityOptions().RetryBackoff * 30,
				},
			),
			"LearnFromExecutionActivity",
			taskID,
			fmt.Sprintf("Result from %s", taskID),
			[]string{"parallel", taskID},
		)
		futures[i] = future
	}

	// Collect results
	results := make([]string, len(futures))
	for i, future := range futures {
		err := future.Get(ctx, &results[i])
		if err != nil {
			return nil, fmt.Errorf("parallel learn task %d: %w", i, err)
		}
	}

	return results, nil
}
