/**
 * rChats Automerge document schemas.
 *
 * Granularity: one directory doc per space + one doc per channel.
 * DocId format: {space}:chats:channels (directory)
 *              {space}:chats:channel:{channelId} (messages)
 *              {space}:chats:dm:{sortedDid1+Did2} (DM channels)
 */

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

// ── Transclusion: structured ref to any rSpace object ──

export interface Transclusion {
	module: string;        // "rtasks" | "rcal" | "rdocs" | etc.
	docId: string;
	objectId?: string;
	display: 'inline' | 'card' | 'link';
	snapshot?: { title: string; summary?: string; capturedAt: number };
}

// ── Thread metadata ──

export interface ThreadMeta {
	participantDids: string[];
	lastActivity: number;
	replyCount: number;
}

// ── Document types ──

export interface ChannelInfo {
	id: string;
	name: string;
	description: string;
	isPrivate: boolean;
	isDm: boolean;
	createdBy: string | null;
	createdAt: number;
	updatedAt: number;
	visibility?: import('../../shared/membrane').ObjectVisibility;
}

export interface ChatsDirectoryDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	channels: Record<string, ChannelInfo>;
}

export interface Member {
	userId: string;
	displayName: string;
	joinedAt: number;
}

export interface ChatMessage {
	id: string;
	channelId: string;
	authorId: string;
	authorName: string;
	content: string;
	replyTo: string | null;
	threadId?: string;              // points to root message ID if this is a thread reply
	reactions: Record<string, string[]>;  // emoji → DID[]
	transclusions: Transclusion[];
	editedAt: number | null;
	createdAt: number;
	visibility?: import('../../shared/membrane').ObjectVisibility;
}

export interface ChatChannelDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	channelId: string;
	messages: Record<string, ChatMessage>;
	members: Record<string, Member>;
	threads: Record<string, ThreadMeta>;  // rootMessageId → thread metadata
	pins: string[];                       // pinned message IDs
	isDm: boolean;
}

// ── Schema registration ──

export const chatsDirectorySchema: DocSchema<ChatsDirectoryDoc> = {
	module: 'chats',
	collection: 'channels',
	version: 2,
	init: (): ChatsDirectoryDoc => ({
		meta: {
			module: 'chats',
			collection: 'channels',
			version: 2,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		channels: {},
	}),
};

export const chatChannelSchema: DocSchema<ChatChannelDoc> = {
	module: 'chats',
	collection: 'channel',
	version: 2,
	init: (): ChatChannelDoc => ({
		meta: {
			module: 'chats',
			collection: 'channel',
			version: 2,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		channelId: '',
		messages: {},
		members: {},
		threads: {},
		pins: [],
		isDm: false,
	}),
};

// ── Helpers ──

export function chatsDirectoryDocId(space: string) {
	return `${space}:chats:channels` as const;
}

export function chatChannelDocId(space: string, channelId: string) {
	return `${space}:chats:channel:${channelId}` as const;
}

export function dmChannelDocId(space: string, did1: string, did2: string): string {
	const sorted = [did1, did2].sort();
	return `${space}:chats:dm:${sorted[0]}+${sorted[1]}`;
}
