/**
 * rSchedule Automerge document schemas.
 *
 * Granularity: one Automerge document per space (all jobs + execution log).
 * DocId format: {space}:schedule:jobs
 */

import type { DocSchema } from '../../shared/local-first/document';

// ── Document types ──

export type ActionType = 'email' | 'webhook' | 'calendar-event' | 'broadcast' | 'backlog-briefing' | 'calendar-reminder';

export interface ScheduleJob {
	id: string;
	name: string;
	description: string;
	enabled: boolean;

	// Timing
	cronExpression: string;
	timezone: string;

	// Action
	actionType: ActionType;
	actionConfig: Record<string, unknown>;

	// Execution state
	lastRunAt: number | null;
	lastRunStatus: 'success' | 'error' | null;
	lastRunMessage: string;
	nextRunAt: number | null;
	runCount: number;

	// Metadata
	createdBy: string;
	createdAt: number;
	updatedAt: number;
}

export interface ExecutionLogEntry {
	id: string;
	jobId: string;
	status: 'success' | 'error';
	message: string;
	durationMs: number;
	timestamp: number;
}

export interface Reminder {
	id: string;
	title: string;
	description: string;
	remindAt: number;          // epoch ms — when to fire
	allDay: boolean;
	timezone: string;
	notifyEmail: string | null;
	notified: boolean;         // has email been sent?
	completed: boolean;        // dismissed by user?

	// Cross-module reference (null for free-form reminders)
	sourceModule: string | null;   // "rtasks", "rnotes", etc.
	sourceEntityId: string | null;
	sourceLabel: string | null;    // "rTasks Task"
	sourceColor: string | null;    // "#f97316"

	// Optional recurrence
	cronExpression: string | null;

	// Link to rCal event (bidirectional)
	calendarEventId: string | null;

	createdBy: string;
	createdAt: number;
	updatedAt: number;
}

// ── Workflow / Automation types ──

export type AutomationNodeType =
	// Triggers
	| 'trigger-cron'
	| 'trigger-data-change'
	| 'trigger-webhook'
	| 'trigger-manual'
	| 'trigger-proximity'
	// Conditions
	| 'condition-compare'
	| 'condition-geofence'
	| 'condition-time-window'
	| 'condition-data-filter'
	// Actions
	| 'action-send-email'
	| 'action-post-webhook'
	| 'action-create-event'
	| 'action-create-task'
	| 'action-send-notification'
	| 'action-update-data';

export type AutomationNodeCategory = 'trigger' | 'condition' | 'action';

export interface WorkflowNodePort {
	name: string;
	type: 'trigger' | 'data' | 'boolean';
}

export interface WorkflowNode {
	id: string;
	type: AutomationNodeType;
	label: string;
	position: { x: number; y: number };
	config: Record<string, unknown>;
	// Runtime state (not persisted to Automerge — set during execution)
	runtimeStatus?: 'idle' | 'running' | 'success' | 'error';
	runtimeMessage?: string;
	runtimeDurationMs?: number;
}

export interface WorkflowEdge {
	id: string;
	fromNode: string;
	fromPort: string;
	toNode: string;
	toPort: string;
}

export interface Workflow {
	id: string;
	name: string;
	enabled: boolean;
	nodes: WorkflowNode[];
	edges: WorkflowEdge[];
	lastRunAt: number | null;
	lastRunStatus: 'success' | 'error' | null;
	runCount: number;
	createdAt: number;
	updatedAt: number;
}

export interface AutomationNodeDef {
	type: AutomationNodeType;
	category: AutomationNodeCategory;
	label: string;
	icon: string;
	description: string;
	inputs: WorkflowNodePort[];
	outputs: WorkflowNodePort[];
	configSchema: { key: string; label: string; type: 'text' | 'number' | 'select' | 'textarea' | 'cron'; options?: string[]; placeholder?: string }[];
}

export const NODE_CATALOG: AutomationNodeDef[] = [
	// ── Triggers ──
	{
		type: 'trigger-cron',
		category: 'trigger',
		label: 'Cron Schedule',
		icon: '⏰',
		description: 'Fire on a cron schedule',
		inputs: [],
		outputs: [{ name: 'trigger', type: 'trigger' }, { name: 'timestamp', type: 'data' }],
		configSchema: [
			{ key: 'cronExpression', label: 'Cron Expression', type: 'cron', placeholder: '0 9 * * *' },
			{ key: 'timezone', label: 'Timezone', type: 'text', placeholder: 'America/Vancouver' },
		],
	},
	{
		type: 'trigger-data-change',
		category: 'trigger',
		label: 'Data Change',
		icon: '📊',
		description: 'Fire when data changes in any rApp',
		inputs: [],
		outputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		configSchema: [
			{ key: 'module', label: 'Module', type: 'select', options: ['rnotes', 'rtasks', 'rcal', 'rnetwork', 'rfiles', 'rvote', 'rflows'] },
			{ key: 'field', label: 'Field to Watch', type: 'text', placeholder: 'status' },
		],
	},
	{
		type: 'trigger-webhook',
		category: 'trigger',
		label: 'Webhook Incoming',
		icon: '🔗',
		description: 'Fire when an external webhook is received',
		inputs: [],
		outputs: [{ name: 'trigger', type: 'trigger' }, { name: 'payload', type: 'data' }],
		configSchema: [
			{ key: 'hookId', label: 'Hook ID', type: 'text', placeholder: 'auto-generated' },
		],
	},
	{
		type: 'trigger-manual',
		category: 'trigger',
		label: 'Manual Trigger',
		icon: '👆',
		description: 'Fire manually via button click',
		inputs: [],
		outputs: [{ name: 'trigger', type: 'trigger' }],
		configSchema: [],
	},
	{
		type: 'trigger-proximity',
		category: 'trigger',
		label: 'Location Proximity',
		icon: '📍',
		description: 'Fire when a location approaches a point',
		inputs: [],
		outputs: [{ name: 'trigger', type: 'trigger' }, { name: 'distance', type: 'data' }],
		configSchema: [
			{ key: 'lat', label: 'Latitude', type: 'number', placeholder: '49.2827' },
			{ key: 'lng', label: 'Longitude', type: 'number', placeholder: '-123.1207' },
			{ key: 'radiusKm', label: 'Radius (km)', type: 'number', placeholder: '1' },
		],
	},
	// ── Conditions ──
	{
		type: 'condition-compare',
		category: 'condition',
		label: 'Compare Values',
		icon: '⚖️',
		description: 'Compare two values',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'value', type: 'data' }],
		outputs: [{ name: 'true', type: 'trigger' }, { name: 'false', type: 'trigger' }],
		configSchema: [
			{ key: 'operator', label: 'Operator', type: 'select', options: ['equals', 'not-equals', 'greater-than', 'less-than', 'contains'] },
			{ key: 'compareValue', label: 'Compare To', type: 'text', placeholder: 'value' },
		],
	},
	{
		type: 'condition-geofence',
		category: 'condition',
		label: 'Geofence Check',
		icon: '🗺️',
		description: 'Check if coordinates are within a radius',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'coords', type: 'data' }],
		outputs: [{ name: 'inside', type: 'trigger' }, { name: 'outside', type: 'trigger' }],
		configSchema: [
			{ key: 'centerLat', label: 'Center Lat', type: 'number', placeholder: '49.2827' },
			{ key: 'centerLng', label: 'Center Lng', type: 'number', placeholder: '-123.1207' },
			{ key: 'radiusKm', label: 'Radius (km)', type: 'number', placeholder: '5' },
		],
	},
	{
		type: 'condition-time-window',
		category: 'condition',
		label: 'Time Window',
		icon: '🕐',
		description: 'Check if current time is within a window',
		inputs: [{ name: 'trigger', type: 'trigger' }],
		outputs: [{ name: 'in-window', type: 'trigger' }, { name: 'outside', type: 'trigger' }],
		configSchema: [
			{ key: 'startHour', label: 'Start Hour (0-23)', type: 'number', placeholder: '9' },
			{ key: 'endHour', label: 'End Hour (0-23)', type: 'number', placeholder: '17' },
			{ key: 'days', label: 'Days', type: 'text', placeholder: '1,2,3,4,5' },
		],
	},
	{
		type: 'condition-data-filter',
		category: 'condition',
		label: 'Data Filter',
		icon: '🔍',
		description: 'Filter data by field value',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'match', type: 'trigger' }, { name: 'no-match', type: 'trigger' }, { name: 'filtered', type: 'data' }],
		configSchema: [
			{ key: 'field', label: 'Field Path', type: 'text', placeholder: 'status' },
			{ key: 'operator', label: 'Operator', type: 'select', options: ['equals', 'not-equals', 'contains', 'exists'] },
			{ key: 'value', label: 'Value', type: 'text', placeholder: 'completed' },
		],
	},
	// ── Actions ──
	{
		type: 'action-send-email',
		category: 'action',
		label: 'Send Email',
		icon: '📧',
		description: 'Send an email via SMTP',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'done', type: 'trigger' }, { name: 'result', type: 'data' }],
		configSchema: [
			{ key: 'to', label: 'To', type: 'text', placeholder: 'user@example.com' },
			{ key: 'subject', label: 'Subject', type: 'text', placeholder: 'Notification from rSpace' },
			{ key: 'bodyTemplate', label: 'Body (HTML)', type: 'textarea', placeholder: '<p>Hello {{name}}</p>' },
		],
	},
	{
		type: 'action-post-webhook',
		category: 'action',
		label: 'POST Webhook',
		icon: '🌐',
		description: 'Send an HTTP POST to an external URL',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'done', type: 'trigger' }, { name: 'response', type: 'data' }],
		configSchema: [
			{ key: 'url', label: 'URL', type: 'text', placeholder: 'https://api.example.com/hook' },
			{ key: 'method', label: 'Method', type: 'select', options: ['POST', 'PUT', 'PATCH'] },
			{ key: 'bodyTemplate', label: 'Body Template', type: 'textarea', placeholder: '{"event": "{{event}}"}' },
		],
	},
	{
		type: 'action-create-event',
		category: 'action',
		label: 'Create Calendar Event',
		icon: '📅',
		description: 'Create an event in rCal',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'done', type: 'trigger' }, { name: 'eventId', type: 'data' }],
		configSchema: [
			{ key: 'title', label: 'Event Title', type: 'text', placeholder: 'Meeting' },
			{ key: 'durationMinutes', label: 'Duration (min)', type: 'number', placeholder: '60' },
		],
	},
	{
		type: 'action-create-task',
		category: 'action',
		label: 'Create Task',
		icon: '✅',
		description: 'Create a task in rTasks',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'done', type: 'trigger' }, { name: 'taskId', type: 'data' }],
		configSchema: [
			{ key: 'title', label: 'Task Title', type: 'text', placeholder: 'New task' },
			{ key: 'description', label: 'Description', type: 'textarea', placeholder: 'Task details...' },
			{ key: 'priority', label: 'Priority', type: 'select', options: ['low', 'medium', 'high', 'urgent'] },
		],
	},
	{
		type: 'action-send-notification',
		category: 'action',
		label: 'Send Notification',
		icon: '🔔',
		description: 'Send an in-app notification',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'done', type: 'trigger' }],
		configSchema: [
			{ key: 'title', label: 'Title', type: 'text', placeholder: 'Notification' },
			{ key: 'message', label: 'Message', type: 'textarea', placeholder: 'Something happened...' },
			{ key: 'level', label: 'Level', type: 'select', options: ['info', 'warning', 'error', 'success'] },
		],
	},
	{
		type: 'action-update-data',
		category: 'action',
		label: 'Update Data',
		icon: '💾',
		description: 'Update data in an rApp document',
		inputs: [{ name: 'trigger', type: 'trigger' }, { name: 'data', type: 'data' }],
		outputs: [{ name: 'done', type: 'trigger' }, { name: 'result', type: 'data' }],
		configSchema: [
			{ key: 'module', label: 'Target Module', type: 'select', options: ['rnotes', 'rtasks', 'rcal', 'rnetwork'] },
			{ key: 'operation', label: 'Operation', type: 'select', options: ['create', 'update', 'delete'] },
			{ key: 'template', label: 'Data Template (JSON)', type: 'textarea', placeholder: '{"field": "{{value}}"}' },
		],
	},
];

export interface ScheduleDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	jobs: Record<string, ScheduleJob>;
	reminders: Record<string, Reminder>;
	workflows: Record<string, Workflow>;
	log: ExecutionLogEntry[];
}

// ── Schema registration ──

export const scheduleSchema: DocSchema<ScheduleDoc> = {
	module: 'schedule',
	collection: 'jobs',
	version: 1,
	init: (): ScheduleDoc => ({
		meta: {
			module: 'schedule',
			collection: 'jobs',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		jobs: {},
		reminders: {},
		workflows: {},
		log: [],
	}),
};

// ── Helpers ──

export function scheduleDocId(space: string) {
	return `${space}:schedule:jobs` as const;
}

/** Maximum execution log entries to keep per doc */
export const MAX_LOG_ENTRIES = 200;

/** Maximum reminders per space */
export const MAX_REMINDERS = 500;
