import { parseCanonicalResourceUri } from "@atcute/lexicons/syntax";
import {
datetimeOf,
didOf,
nsidOf,
recordKeyOf,
type AtUri,
type KnotOrigin
} from "#lib/api/syntax.ts";
import { now as tidNow } from "@atcute/tid";
import type { OAuthUserAgent } from "@atcute/oauth-browser-client";
import type { BobbinContext, XrpcRequestInit } from "#lib/api/client.ts";
import { jsonGet } from "#lib/api/_request.ts";
import type { RecordView } from "#lib/api/records.ts";
import { cobRefOf, createCob, eraseCob, type CobRef } from "#lib/api/cob.ts";
import { rkeyFromUri } from "#lib/api/uri.ts";
import { deleteRecord, putRecord } from "#lib/api/write.ts";
import type * as OrgTangledFeedReaction from "#lib/api/lexicons/types/org/tangled/feed/reaction.ts";
export type ReactionRecord = OrgTangledFeedReaction.Main;
export const REACTION_COLLECTION = nsidOf("org.tangled.feed.reaction");
export interface ViewerReaction {
uri: string;
cid?: string;
}
// without a knot this is a string reaction on the writer's pds
export const react = async (
agent: OAuthUserAgent,
knot: KnotOrigin | undefined,
subject: CobRef,
reaction: ReactionRecord["reaction"]
): Promise<CobRef> => {
const record: ReactionRecord = {
$type: "org.tangled.feed.reaction",
subject,
reaction,
createdAt: datetimeOf(new Date().toISOString())
};
if (!knot) return putRecord(agent, REACTION_COLLECTION, recordKeyOf(tidNow()), record);
const { repo } = parseCanonicalResourceUri(subject.uri);
return createCob(agent, knot, didOf(repo), REACTION_COLLECTION, record);
};
export const unreact = async (
agent: OAuthUserAgent,
knot: KnotOrigin | undefined,
mine: ViewerReaction
): Promise<void> => {
if (!knot) return deleteRecord(agent, REACTION_COLLECTION, rkeyFromUri(mine.uri));
await eraseCob(agent, knot, cobRefOf(mine));
};
export interface ReactionListPage {
cursor?: string | null;
items: RecordView<ReactionRecord>[];
}
export const listReactions = (
ctx: BobbinContext,
subject: AtUri,
filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {},
init?: XrpcRequestInit
) => jsonGet<ReactionListPage>(ctx, "org.tangled.feed.listReactions", { subject, ...filter }, init);