// Type mirrors of the Rust DTOs. Keep these in sync by hand — comments call out the
// originating source file so future-you can grep both sides. See
// `frontend/src/lib/README.md` for the convention.

// mirrors backend/src/handlers/feed.rs::FeedUpload
export interface FeedUpload {
	id: string;
	user_id: string;
	uploader_name: string;
	preview_url: string | null;
	thumbnail_url: string | null;
	/** Big-screen (~2048px) variant for the diashow; null until the derivative exists. */
	display_url: string | null;
	mime_type: string;
	caption: string | null;
	like_count: number;
	comment_count: number;
	liked_by_me: boolean;
	created_at: string;
}

// mirrors backend/src/handlers/feed.rs::FeedResponse
export interface FeedResponse {
	uploads: FeedUpload[];
	next_cursor: string | null;
}

// mirrors backend/src/handlers/feed.rs::DeltaResponse
export interface DeltaResponse {
	uploads: FeedUpload[];
	deleted_ids: string[];
	// Users hidden (banned / uploads_hidden) since the cursor. A ban is not a soft-delete so
	// it's absent from deleted_ids; the client evicts all uploads from these users, which
	// replays a ban the client missed while disconnected (esp. the unattended projector).
	hidden_user_ids: string[];
	// True when the delta hit the backend cap and is only the newest slice of the
	// gap — the client must full-refresh rather than merge (see feed-delta handler).
	truncated: boolean;
	// Server clock when this delta was computed — the next reconnect cursor advances
	// from THIS, never the browser clock, so clock skew can't silently drop uploads.
	server_time: string;
}

// mirrors backend/src/handlers/feed.rs::HashtagCount
export interface HashtagCount {
	tag: string;
	count: number;
}

// mirrors backend/src/handlers/me.rs::QuotaDto
export interface QuotaDto {
	enabled: boolean;
	used_bytes: number;
	limit_bytes: number | null;
	active_uploaders: number;
	free_disk_bytes: number;
}

// mirrors backend/src/handlers/me.rs::MeContextDto
export interface MeContextDto {
	user_id: string;
	display_name: string;
	role: 'guest' | 'host' | 'admin';
	/** Plain text — preserve whitespace and newlines on render; do **not** parse as HTML. */
	privacy_note: string;
	quota_enabled: boolean;
	storage_quota_enabled: boolean;
	uploads_locked: boolean;
	gallery_released: boolean;
	/** Read-only ban: the feed and the keepsake stay available, every write is refused. */
	is_banned: boolean;
}

// mirrors backend/src/handlers/host.rs::PinResetResponse
export interface PinResetResponse {
	/** One-time plaintext PIN. Show it to the operator once, then forget it. */
	pin: string;
}
