/**
 * rCred — Contribution Recognition via CredRank.
 *
 * Types + DocSchema definitions for contribution graphs, cred scores,
 * and grain distribution config.
 *
 * Doc IDs:
 *   {space}:rcred:graph   → ContribGraphDoc
 *   {space}:rcred:scores  → CredScoresDoc
 *   {space}:rcred:config  → CredConfigDoc
 */

import type { DocSchema } from '../../shared/module';

// ── Graph types ──

export type CredNodeType = 'contributor' | 'contribution';
export type CredEdgeType = 'authored' | 'commented-on' | 'reacted-to' | 'attended' | 'voted-on' | 'completed';

export interface CredNode {
	id: string;
	type: CredNodeType;
	/** DID for contributor nodes */
	did?: string;
	label: string;
	sourceModule: string;
	contributionType: string;
	timestamp: number;
	weight: number;
}

export interface CredEdge {
	id: string;
	from: string;
	to: string;
	type: CredEdgeType;
	weight: number;
}

export interface ContribGraphDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	nodes: Record<string, CredNode>;
	edges: Record<string, CredEdge>;
	lastBuiltAt: number;
	stats: {
		nodeCount: number;
		edgeCount: number;
		contributorCount: number;
		contributionCount: number;
	};
}

// ── Score types ──

export interface CredScore {
	did: string;
	label: string;
	cred: number;
	rawScore: number;
	grainLifetime: number;
	epochScores: Record<string, number>;
	/** Module → cred contribution */
	breakdown: Record<string, number>;
	lastActive: number;
}

export interface CredScoresDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	scores: Record<string, CredScore>;
	totalCred: number;
	computedAt: number;
	epochId: string;
}

// ── Config types ──

export interface ContributionTypeWeight {
	type: string;
	weight: number;
	description: string;
}

export interface CredConfigDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	weights: Record<string, ContributionTypeWeight>;
	grainPerEpoch: number;
	epochLengthDays: number;
	/** Fraction of grain allocated to lifetime equity (0-1) */
	slowFraction: number;
	/** Fraction of grain allocated to current epoch (0-1) */
	fastFraction: number;
	/** PageRank damping factor (α in teleportation probability) */
	dampingFactor: number;
	lookbackDays: number;
	enabled: boolean;
	lastEpochAt: number;
	grainTokenId: string;
}

// ── Default contribution weights ──

export const DEFAULT_WEIGHTS: Record<string, ContributionTypeWeight> = {
	'task-created':         { type: 'task-created',         weight: 1.0, description: 'Created a task' },
	'task-completed':       { type: 'task-completed',       weight: 3.0, description: 'Completed a task' },
	'doc-authored':         { type: 'doc-authored',         weight: 2.0, description: 'Authored a document' },
	'comment-authored':     { type: 'comment-authored',     weight: 1.0, description: 'Wrote a comment' },
	'message-sent':         { type: 'message-sent',         weight: 0.5, description: 'Sent a chat message' },
	'reaction-given':       { type: 'reaction-given',       weight: 0.2, description: 'Reacted to a message' },
	'event-scheduled':      { type: 'event-scheduled',      weight: 2.0, description: 'Scheduled an event' },
	'event-attended':       { type: 'event-attended',       weight: 1.5, description: 'Attended an event' },
	'proposal-authored':    { type: 'proposal-authored',    weight: 3.0, description: 'Authored a proposal' },
	'vote-cast':            { type: 'vote-cast',            weight: 1.0, description: 'Cast a vote' },
	'flow-created':         { type: 'flow-created',         weight: 2.0, description: 'Created a flow' },
	'budget-allocated':     { type: 'budget-allocated',     weight: 1.5, description: 'Allocated budget' },
	'commitment-created':   { type: 'commitment-created',   weight: 2.0, description: 'Created a time commitment' },
	'settlement-completed': { type: 'settlement-completed', weight: 4.0, description: 'Settled a time commitment' },
	'address-added':        { type: 'address-added',        weight: 1.0, description: 'Added a wallet address' },
	'tx-annotated':         { type: 'tx-annotated',         weight: 0.5, description: 'Annotated a transaction' },
};

// ── Doc ID helpers ──

export function graphDocId(space: string) {
	return `${space}:rcred:graph` as const;
}

export function scoresDocId(space: string) {
	return `${space}:rcred:scores` as const;
}

export function configDocId(space: string) {
	return `${space}:rcred:config` as const;
}

// ── DocSchema definitions (for module registration) ──

export const graphSchema: DocSchema<ContribGraphDoc> = {
	pattern: '{space}:rcred:graph',
	description: 'Contribution graph — nodes and edges from all module activity',
	init: (): ContribGraphDoc => ({
		meta: { module: 'rcred', collection: 'graph', version: 1, spaceSlug: '', createdAt: Date.now() },
		nodes: {},
		edges: {},
		lastBuiltAt: 0,
		stats: { nodeCount: 0, edgeCount: 0, contributorCount: 0, contributionCount: 0 },
	}),
};

export const scoresSchema: DocSchema<CredScoresDoc> = {
	pattern: '{space}:rcred:scores',
	description: 'CredRank scores — per-contributor cred and grain tallies',
	init: (): CredScoresDoc => ({
		meta: { module: 'rcred', collection: 'scores', version: 1, spaceSlug: '', createdAt: Date.now() },
		scores: {},
		totalCred: 0,
		computedAt: 0,
		epochId: '',
	}),
};

export const configSchema: DocSchema<CredConfigDoc> = {
	pattern: '{space}:rcred:config',
	description: 'CredRank configuration — contribution weights and grain parameters',
	init: (): CredConfigDoc => ({
		meta: { module: 'rcred', collection: 'config', version: 1, spaceSlug: '', createdAt: Date.now() },
		weights: { ...DEFAULT_WEIGHTS },
		grainPerEpoch: 1000,
		epochLengthDays: 7,
		slowFraction: 0.8,
		fastFraction: 0.2,
		dampingFactor: 0.15,
		lookbackDays: 90,
		enabled: true,
		lastEpochAt: 0,
		grainTokenId: '',
	}),
};
