/**
 * rCal Automerge document schemas.
 *
 * Granularity: one Automerge document per space (all events + sources).
 * DocId format: {space}:cal:events
 */

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

// ── Document types ──

export interface CalendarSource {
	id: string;
	name: string;
	sourceType: string;
	url: string | null;
	color: string | null;
	isActive: boolean;
	isVisible: boolean;
	syncIntervalMinutes: number | null;
	lastSyncedAt: number;
	ownerId: string | null;
	createdAt: number;
	/** External calendar ID (e.g. Google Calendar ID like "user@gmail.com") */
	externalId?: string | null;
	/** Google Calendar incremental sync token */
	syncToken?: string | null;
	/** Status of last sync attempt */
	lastSyncStatus?: string | null;
	/** Error message if last sync failed */
	lastSyncError?: string | null;
	/** Number of events from this source */
	eventCount?: number | null;
}

export interface EventAttendee {
	name: string;
	email?: string;
	status: 'yes' | 'no' | 'maybe' | 'pending';
	respondedAt: number;
	source: 'magic-link' | 'app' | 'import';
	/** Prevent duplicate responses from same magic link */
	tokenHash?: string;
}

export interface CalendarEvent {
	id: string;
	title: string;
	description: string;
	startTime: number;
	endTime: number;
	allDay: boolean;
	timezone: string | null;
	rrule: string | null;
	status: string | null;
	likelihood: number | null; // 0-100, null = confirmed (100%)
	visibility: string | null;
	sourceId: string | null;
	sourceName: string | null;
	sourceType: string | null;
	sourceColor: string | null;
	locationId: string | null;
	locationName: string | null;
	coordinates: { x: number; y: number } | null;
	locationGranularity: string | null;
	locationLat: number | null;
	locationLng: number | null;
	isVirtual: boolean;
	virtualUrl: string | null;
	virtualPlatform: string | null;
	rToolSource: string | null;
	rToolEntityId: string | null;
	locationBreadcrumb: string | null; // "Earth > Europe > Germany > Berlin"
	bookingStatus: string | null; // "booked" | "unbooked" | null (placeholder for booking pipeline)
	attendees: EventAttendee[];
	attendeeCount: number;
	tags: string[] | null;
	metadata: unknown | null;
	createdAt: number;
	updatedAt: number;
	accessVisibility?: import('../../shared/membrane').ObjectVisibility;
}

export interface SavedCalendarViewFilter {
	tags?: string[];
	sourceIds?: string[];
	search?: string;
	locationName?: string;
	isVirtual?: boolean;
	rToolSource?: string;
}

export interface SavedCalendarView {
	id: string;
	name: string;
	icon: string | null;
	filter: SavedCalendarViewFilter;
	defaultViewMode: string | null;
	createdAt: number;
	updatedAt: number;
}

export interface CalendarDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	sources: Record<string, CalendarSource>;
	events: Record<string, CalendarEvent>;
	views: Record<string, SavedCalendarView>;
}

// ── Schema registration ──

export const calendarSchema: DocSchema<CalendarDoc> = {
	module: 'cal',
	collection: 'events',
	version: 1,
	init: (): CalendarDoc => ({
		meta: {
			module: 'cal',
			collection: 'events',
			version: 1,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		sources: {},
		events: {},
		views: {},
	}),
};

// ── KOI-Inspired Provenance (stored in CalendarEvent.metadata) ──

/** Lifecycle events following BlockScience KOI's RID pattern */
export type ProvenanceLifecycle = 'NEW' | 'UPDATE' | 'FORGET';

/** KOI-inspired provenance — stored in CalendarEvent.metadata.provenance */
export interface KnowledgeProvenance {
	/** Reference identifier in "type:uuid" format, e.g. "folk-note:abc-123" */
	rid: string;
	/** SHA-256 hex digest of content at scheduling time */
	contentHash: string | null;
	/** Shape type that originated this item (e.g. "folk-note", "folk-photo") */
	sourceType: string;
	/** Space slug where the item lives */
	sourceSpace: string;
	/** KOI lifecycle event */
	lifecycleEvent: ProvenanceLifecycle;
	/** Original creation timestamp of the source item (epoch ms) */
	originalCreatedAt: number;
	/** DID or user identifier who scheduled this */
	scheduledBy: string | null;
	/** When the scheduling action occurred (epoch ms) */
	scheduledAt: number;
}

/** Preview snapshot for email rendering — stored in metadata.itemPreview */
export interface ItemPreview {
	/** First ~200 chars of content */
	textPreview: string;
	/** MIME type: text/markdown, image/jpeg, etc. */
	mimeType: string;
	/** Thumbnail URL for photos/media */
	thumbnailUrl?: string;
	/** Deep link back to canvas shape */
	canvasUrl?: string;
	/** Full serialized shape data for reconstruction */
	shapeSnapshot?: Record<string, unknown>;
}

/** Typed metadata shape when CalendarEvent represents a scheduled knowledge item */
export interface ScheduledItemMetadata {
	isScheduledItem: true;
	provenance: KnowledgeProvenance;
	itemPreview: ItemPreview;
	reminderSent: boolean;
	reminderSentAt: number | null;
}

// ── Helpers ──

export function calendarDocId(space: string) {
	return `${space}:cal:events` as const;
}
