/**
 * Flow types — framework-agnostic (ported from rflows-online, @xyflow removed).
 */

export interface IntegrationSource {
	type: "rvote" | "safe" | "manual";
	safeAddress?: string;
	safeChainId?: number;
	tokenAddress?: string | null;
	tokenSymbol?: string;
	tokenDecimals?: number;
	rvoteSpaceSlug?: string;
	rvoteProposalId?: string;
	rvoteProposalStatus?: string;
	rvoteProposalScore?: number;
	lastFetchedAt?: number;
}

export interface OverflowAllocation {
	targetId: string;
	percentage: number;
	color: string;
	waypoint?: { x: number; y: number };
}

export interface SpendingAllocation {
	targetId: string;
	percentage: number;
	color: string;
	waypoint?: { x: number; y: number };
}

export interface SourceAllocation {
	targetId: string;
	percentage: number;
	color: string;
	waypoint?: { x: number; y: number };
}

export type SufficiencyState = "seeking" | "sufficient" | "abundant";

export interface FunnelNodeData {
	label: string;
	currentValue: number;
	minThreshold: number;
	maxThreshold: number;
	maxCapacity: number;
	inflowRate: number;
	desiredOutflow?: number;
	sufficientThreshold?: number;
	dynamicOverflow?: boolean;
	overflowAllocations: OverflowAllocation[];
	spendingAllocations: SpendingAllocation[];
	source?: IntegrationSource;
	[key: string]: unknown;
}

export function deriveThresholds(desiredOutflow: number) {
	return {
		minThreshold:        desiredOutflow * 1,   // 1 month runway
		sufficientThreshold: desiredOutflow * 3,   // 3 months runway
		maxThreshold:        desiredOutflow * 6,   // overflow point
		maxCapacity:         desiredOutflow * 9,   // visual max
	};
}

export interface PhaseTask {
	label: string;
	completed: boolean;
}

export interface OutcomePhase {
	name: string;
	fundingThreshold: number;
	tasks: PhaseTask[];
}

export interface OutcomeNodeData {
	label: string;
	description?: string;
	fundingReceived: number;
	fundingTarget: number;
	status: "not-started" | "in-progress" | "completed" | "blocked";
	phases?: OutcomePhase[];
	overflowAllocations?: OverflowAllocation[];
	source?: IntegrationSource;
	[key: string]: unknown;
}

export interface SourceNodeData {
	label: string;
	flowRate: number;
	sourceType: "card" | "safe_wallet" | "ridentity" | "unconfigured";
	targetAllocations: SourceAllocation[];
	walletAddress?: string;
	chainId?: number;
	safeAddress?: string;
	transakOrderId?: string;
	[key: string]: unknown;
}

/** Lightweight node (replaces @xyflow/react Node) */
export interface FlowNode {
	id: string;
	type: "funnel" | "outcome" | "source";
	position: { x: number; y: number };
	data: FunnelNodeData | OutcomeNodeData | SourceNodeData;
}

// ─── Port definitions ─────────────────────────────────

export type PortDirection = "in" | "out";
export type PortKind = "outflow" | "inflow" | "spending" | "overflow";

export interface PortDefinition {
	kind: PortKind;
	dir: PortDirection;
	/** X offset as fraction of node width (0–1) */
	xFrac: number;
	/** Y offset: 0 = top, 1 = bottom */
	yFrac: number;
	color: string;
	/** Which port kinds this output can wire to */
	connectsTo?: PortKind[];
	/** For side-mounted ports (overflow lips) */
	side?: "left" | "right";
}

/** Single source of truth for port positions, colors, and connectivity rules. */
export const PORT_DEFS: Record<FlowNode["type"], PortDefinition[]> = {
	source: [
		{ kind: "outflow", dir: "out", xFrac: 0.5, yFrac: 1, color: "#10b981", connectsTo: ["inflow"] },
	],
	funnel: [
		{ kind: "inflow",   dir: "in",  xFrac: 0.5, yFrac: 0,    color: "#60a5fa" },
		{ kind: "overflow", dir: "out", xFrac: 0.0, yFrac: 0.55, color: "#f59e0b", connectsTo: ["inflow"], side: "left" },
		{ kind: "overflow", dir: "out", xFrac: 1.0, yFrac: 0.55, color: "#f59e0b", connectsTo: ["inflow"], side: "right" },
		{ kind: "spending", dir: "out", xFrac: 0.5, yFrac: 1,    color: "#8b5cf6", connectsTo: ["inflow"] },
	],
	outcome: [
		{ kind: "inflow",   dir: "in",  xFrac: 0.5, yFrac: 0, color: "#60a5fa" },
		{ kind: "overflow", dir: "out", xFrac: 0.5, yFrac: 1, color: "#f59e0b", connectsTo: ["inflow"] },
	],
};
