/**
 * Maps TBFF API response data to FlowNode[] for visualization.
 * Shared between folk-flows-app (data loading) and folk-flow-river (rendering).
 */

import { migrateFunnelNodeData, type FlowNode, type FunnelNodeData, type OutcomeNodeData, type SourceNodeData } from "./types";

const SPENDING_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#06b6d4", "#10b981", "#6366f1"];
const OVERFLOW_COLORS = ["#f59e0b", "#ef4444", "#f97316", "#eab308", "#dc2626", "#ea580c"];

export function mapFlowToNodes(apiData: any): FlowNode[] {
	const nodes: FlowNode[] = [];

	// Map sources (income/deposit streams)
	if (apiData.sources) {
		for (const src of apiData.sources) {
			nodes.push({
				id: src.id,
				type: "source",
				position: { x: 0, y: 0 },
				data: {
					label: src.label || src.name || "Source",
					flowRate: src.flowRate ?? src.amount ?? 0,
					sourceType: src.sourceType || "card",
					targetAllocations: (src.targetAllocations || src.allocations || []).map((a: any, i: number) => ({
						targetId: a.targetId,
						percentage: a.percentage,
						color: a.color || SPENDING_COLORS[i % SPENDING_COLORS.length],
					})),
				} as SourceNodeData,
			});
		}
	}

	// Map funnels (budget buckets)
	if (apiData.funnels) {
		for (const funnel of apiData.funnels) {
			nodes.push({
				id: funnel.id,
				type: "funnel",
				position: { x: 0, y: 0 },
				data: migrateFunnelNodeData({
					...funnel,
					label: funnel.label || funnel.name || "Funnel",
					currentValue: funnel.currentValue ?? funnel.balance ?? 0,
					overflowAllocations: (funnel.overflowAllocations || []).map((a: any, i: number) => ({
						targetId: a.targetId,
						percentage: a.percentage,
						color: a.color || OVERFLOW_COLORS[i % OVERFLOW_COLORS.length],
					})),
					spendingAllocations: (funnel.spendingAllocations || []).map((a: any, i: number) => ({
						targetId: a.targetId,
						percentage: a.percentage,
						color: a.color || SPENDING_COLORS[i % SPENDING_COLORS.length],
					})),
				}),
			});
		}
	}

	// Map outcomes (funding targets)
	if (apiData.outcomes) {
		for (const outcome of apiData.outcomes) {
			nodes.push({
				id: outcome.id,
				type: "outcome",
				position: { x: 0, y: 0 },
				data: {
					label: outcome.label || outcome.name || "Outcome",
					description: outcome.description || "",
					fundingReceived: outcome.fundingReceived ?? outcome.received ?? 0,
					fundingTarget: outcome.fundingTarget ?? outcome.target ?? 0,
					status: outcome.status || "not-started",
				} as OutcomeNodeData,
			});
		}
	}

	return nodes;
}
