/**
 * rDocs Automerge document schemas.
 *
 * Granularity: one Automerge document per notebook.
 * DocId format: {space}:notes:notebooks:{notebookId}
 *
 * IMPORTANT: These are identical to the original rNotes schemas.
 * The docId prefix stays `notes:notebooks` for backward compatibility —
 * existing notebook data is accessible without migration.
 */

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

// ── Document types ──

export interface SourceRef {
	source: 'logseq' | 'obsidian' | 'notion' | 'google-docs' | 'evernote' | 'roam' | 'manual';
	externalId: string;
	lastSyncedAt: number;
	contentHash?: string;
	syncStatus?: 'synced' | 'local-modified' | 'remote-modified' | 'conflict';
}

export interface CommentMessage {
	id: string;
	authorId: string;
	authorName: string;
	text: string;
	createdAt: number;
}

export interface CommentThread {
	id: string;
	anchor: string;
	resolved: boolean;
	messages: CommentMessage[];
	createdAt: number;
}

export interface NoteItem {
	id: string;
	notebookId: string;
	authorId: string | null;
	title: string;
	content: string;
	contentPlain: string;
	contentFormat?: 'html' | 'tiptap-json';
	type: 'NOTE' | 'CLIP' | 'BOOKMARK' | 'CODE' | 'IMAGE' | 'FILE' | 'AUDIO';
	url: string | null;
	language: string | null;
	fileUrl: string | null;
	mimeType: string | null;
	fileSize: number | null;
	duration: number | null;
	isPinned: boolean;
	sortOrder: number;
	tags: string[];
	summary?: string;
	summaryModel?: string;
	openNotebookSourceId?: string;
	sourceRef?: SourceRef;
	conflictContent?: string;
	collabEnabled?: boolean;
	comments?: Record<string, CommentThread>;
	createdAt: number;
	updatedAt: number;
	visibility?: import('../../shared/membrane').ObjectVisibility;
}

export interface NotebookMeta {
	id: string;
	title: string;
	slug: string;
	description: string;
	coverColor: string;
	isPublic: boolean;
	createdAt: number;
	updatedAt: number;
}

export interface NotebookDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	notebook: NotebookMeta;
	items: Record<string, NoteItem>;
}

// ── Schema registration ──

export interface ConnectionsDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	notion?: {
		accessToken: string;
		workspaceId: string;
		workspaceName: string;
		connectedAt: number;
	};
	google?: {
		refreshToken: string;
		accessToken: string;
		expiresAt: number;
		email: string;
		connectedAt: number;
	};
}

/** Generate a docId for a space's integration connections. */
export function connectionsDocId(space: string) {
	return `${space}:notes:connections` as const;
}

export const notebookSchema: DocSchema<NotebookDoc> = {
	module: 'notes',
	collection: 'notebooks',
	version: 5,
	init: (): NotebookDoc => ({
		meta: {
			module: 'notes',
			collection: 'notebooks',
			version: 5,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		notebook: {
			id: '',
			title: 'Untitled Notebook',
			slug: '',
			description: '',
			coverColor: '#3b82f6',
			isPublic: false,
			createdAt: Date.now(),
			updatedAt: Date.now(),
		},
		items: {},
	}),
	migrate: (doc: NotebookDoc, fromVersion: number): NotebookDoc => {
		if (fromVersion < 2) {
			for (const item of Object.values(doc.items)) {
				if (!(item as any).contentFormat) (item as any).contentFormat = 'html';
			}
		}
		return doc;
	},
};

// ── Helpers ──

/** Generate a docId for a notebook. */
export function notebookDocId(space: string, notebookId: string) {
	return `${space}:notes:notebooks:${notebookId}` as const;
}

/** Create a fresh NoteItem with defaults. */
export function createNoteItem(
	id: string,
	notebookId: string,
	title: string,
	opts: Partial<NoteItem> = {},
): NoteItem {
	const now = Date.now();
	return {
		id,
		notebookId,
		authorId: null,
		title,
		content: '',
		contentPlain: '',
		contentFormat: 'tiptap-json',
		type: 'NOTE',
		url: null,
		language: null,
		fileUrl: null,
		mimeType: null,
		fileSize: null,
		duration: null,
		isPinned: false,
		sortOrder: 0,
		tags: [],
		createdAt: now,
		updatedAt: now,
		...opts,
	};
}
