package activity

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

	"github.com/rockliang/poimen/workflows/pkg/db"
)

// FetchCanvasRelationsActivity fetches canvas + relations from DB
func FetchCanvasRelationsActivity(ctx context.Context, input FetchCanvasRelationsInput) (CanvasWithRelationsData, error) {
	logger := newActivityLogger(ctx)
	output := CanvasWithRelationsData{
		WorkflowID: input.WorkflowID,
		Version:    input.Version,
		Nodes:      []db.WorkflowNode{},
		Edges:      []db.WorkflowEdge{},
		Relations:  []EdgeWithWording{},
	}

	logger.Info("Fetching canvas relations: %s v%d", input.WorkflowID, input.Version)

	// Get database client from context or activity manager
	dbClient, ok := ctx.Value("db_client").(*db.DB)
	if !ok {
		return output, fmt.Errorf("database client not in context")
	}

	// Fetch workflow
	workflow, err := dbClient.FetchWorkflow(ctx, input.WorkflowID, "")
	if err != nil {
		return output, fmt.Errorf("failed to get workflow: %w", err)
	}

	// Parse canvas nodes and edges
	var nodes []db.WorkflowNode
	if err := json.Unmarshal([]byte(workflow.Nodes), &nodes); err != nil {
		return output, fmt.Errorf("failed to parse nodes: %w", err)
	}

	var edges []db.WorkflowEdge
	if err := json.Unmarshal([]byte(workflow.Edges), &edges); err != nil {
		return output, fmt.Errorf("failed to parse edges: %w", err)
	}

	output.Nodes = nodes
	output.Edges = edges
	output.UpdatedAt = workflow.UpdatedAt.String()

	// Fetch workflow relations
	relations, err := dbClient.GetWorkflowRelations(ctx, input.WorkflowID, input.Version)
	if err != nil {
		// Relations may not exist for old canvases - this is OK
		logger.Warn("Failed to fetch relations: %v", err)
		return output, nil
	}

	// Map to EdgeWithWording
	for _, rel := range relations {
		edge := EdgeWithWording{
			ID:             rel.ID,
			Source:         rel.SourceNodeID,
			Target:         rel.TargetNodeID,
			RelationType:   rel.RelationType,
			RelationLabel:  rel.Label,
			CreatedAt:      rel.CreatedAt.String(),
		}

		// Parse relation wording JSON
		if err := json.Unmarshal(rel.RelationWording, &edge.RelationWording); err != nil {
			logger.Warn("Failed to parse relation wording: %v", err)
		}

		output.Relations = append(output.Relations, edge)
	}

	logger.Info("Fetched %d nodes, %d edges, %d relations", len(output.Nodes), len(output.Edges), len(output.Relations))
	return output, nil
}
