/**
 * rInbox Automerge document schemas.
 *
 * Granularity: one Automerge document per mailbox.
 * DocId format: {space}:inbox:mailboxes:{mailboxId}
 *
 * IMAP sync stays server-side — Automerge holds thread/comment state.
 */

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

// ── Document types ──

export interface MailboxMember {
	id: string;
	mailboxId: string;
	userId: string;
	role: string;
	joinedAt: number;
}

export interface ThreadComment {
	id: string;
	threadId: string;
	authorId: string;
	body: string;
	contentFormat?: 'html' | 'tiptap-json';
	mentions: string[];
	createdAt: number;
}

export interface ThreadItem {
	id: string;
	mailboxId: string;
	messageId: string | null;
	subject: string;
	fromAddress: string | null;
	fromName: string | null;
	toAddresses: string[];
	ccAddresses: string[];
	bodyText: string;
	bodyHtml: string;
	tags: string[];
	status: string;
	isRead: boolean;
	isStarred: boolean;
	assignedTo: string | null;
	hasAttachments: boolean;
	receivedAt: number;
	createdAt: number;
	comments: ThreadComment[];
	// Threading (RFC 5322)
	inReplyTo: string | null;
	references: string[];
	direction: 'inbound' | 'outbound';
	parentThreadId: string | null;
}

export interface ApprovalSignature {
	id: string;
	approvalId: string;
	signerId: string;
	vote: string;
	signedAt: number;
}

export interface ApprovalItem {
	id: string;
	mailboxId: string;
	threadId: string | null;
	authorId: string;
	subject: string;
	bodyText: string;
	bodyHtml: string;
	toAddresses: string[];
	ccAddresses: string[];
	status: string;
	requiredSignatures: number;
	safeTxHash: string | null;
	createdAt: number;
	resolvedAt: number;
	signatures: ApprovalSignature[];
	// Reply/forward context
	inReplyTo: string | null;
	references: string[];
	replyType: 'reply' | 'reply-all' | 'forward' | 'new';
	// Rich content format
	contentFormat?: 'html' | 'tiptap-json';
	collabEnabled?: boolean;
	// Newsletter approval bridge
	approvalType?: 'email' | 'newsletter';
	listmonkCampaignId?: number | null;
}

// ── Personal Inbox ──

export interface PersonalInbox {
	id: string;
	ownerDid: string;
	label: string;
	email: string;
	imapHost: string;
	imapPort: number;
	smtpHost: string;
	smtpPort: number;
	lastSyncAt: number;
	status: 'active' | 'error' | 'paused';
}

// ── Agent Inbox ──

export interface AgentRule {
	match: { field: 'from' | 'subject' | 'body'; pattern: string };
	action: 'reply' | 'forward' | 'tag' | 'assign';
	value?: string;
}

export interface AgentInbox {
	id: string;
	spaceSlug: string;
	name: string;
	email: string;
	personality: string;
	autoReply: boolean;
	autoClassify: boolean;
	rules: AgentRule[];
}

export interface MailboxMeta {
	id: string;
	workspaceId: string | null;
	slug: string;
	name: string;
	email: string;
	description: string;
	visibility: string;
	ownerDid: string;
	safeAddress: string | null;
	safeChainId: number | null;
	approvalThreshold: number;
	createdAt: number;
}

export interface MailboxDoc {
	meta: {
		module: string;
		collection: string;
		version: number;
		spaceSlug: string;
		createdAt: number;
	};
	mailbox: MailboxMeta;
	members: MailboxMember[];
	threads: Record<string, ThreadItem>;
	approvals: Record<string, ApprovalItem>;
	personalInboxes: Record<string, PersonalInbox>;
	agentInboxes: Record<string, AgentInbox>;
}

// ── Schema registration ──

export const mailboxSchema: DocSchema<MailboxDoc> = {
	module: 'inbox',
	collection: 'mailboxes',
	version: 2,
	init: (): MailboxDoc => ({
		meta: {
			module: 'inbox',
			collection: 'mailboxes',
			version: 2,
			spaceSlug: '',
			createdAt: Date.now(),
		},
		mailbox: {
			id: '',
			workspaceId: null,
			slug: '',
			name: '',
			email: '',
			description: '',
			visibility: 'private',
			ownerDid: '',
			safeAddress: null,
			safeChainId: null,
			approvalThreshold: 1,
			createdAt: Date.now(),
		},
		members: [],
		threads: {},
		approvals: {},
		personalInboxes: {},
		agentInboxes: {},
	}),
};

// ── Helpers ──

export function mailboxDocId(space: string, mailboxId: string) {
	return `${space}:inbox:mailboxes:${mailboxId}` as const;
}
