"use client"; import type { ChatAction, ChatActionEventType, } from "@/data/schemas/chat"; import { chatApi } from "@/data/services/api"; const EVENT_PREFIX = "cozsweet:chat-action-event:v1"; const ARRIVAL_KEY = "cozsweet:chat-action-arrival:v1"; interface PendingChatActionArrival { actionId: string; characterId: string; expectedPath: string; } export async function recordChatActionEvent( action: ChatAction, characterId: string, eventType: ChatActionEventType, ): Promise { await recordChatActionEventById(action.actionId, characterId, eventType); } export async function recordChatActionEventById( actionId: string, characterId: string, eventType: ChatActionEventType, ): Promise { await chatApi.recordActionEvent({ eventId: getOrCreateEventId(actionId, eventType), actionId, characterId, eventType, }); } export function rememberChatActionArrival( action: ChatAction, characterId: string, targetUrl: string, ): void { if (typeof window === "undefined") return; const target = new URL(targetUrl, window.location.origin); if (target.origin !== window.location.origin) return; const pending: PendingChatActionArrival = { actionId: action.actionId, characterId, expectedPath: target.pathname, }; window.sessionStorage.setItem(ARRIVAL_KEY, JSON.stringify(pending)); } export function readPendingChatActionArrival(): PendingChatActionArrival | null { if (typeof window === "undefined") return null; try { const raw = window.sessionStorage.getItem(ARRIVAL_KEY); if (!raw) return null; const parsed = JSON.parse(raw) as Partial; if (!parsed.actionId || !parsed.characterId || !parsed.expectedPath) { return null; } return parsed as PendingChatActionArrival; } catch { return null; } } export function clearPendingChatActionArrival(): void { if (typeof window === "undefined") return; window.sessionStorage.removeItem(ARRIVAL_KEY); } function getOrCreateEventId( actionId: string, eventType: ChatActionEventType, ): string { const key = `${EVENT_PREFIX}:${actionId}:${eventType}`; if (typeof window !== "undefined") { const existing = window.sessionStorage.getItem(key); if (existing) return existing; } const eventId = createUuid(); if (typeof window !== "undefined") { window.sessionStorage.setItem(key, eventId); } return eventId; } function createUuid(): string { if (typeof globalThis.crypto?.randomUUID === "function") { return globalThis.crypto.randomUUID(); } return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (value) => { const random = Math.floor(Math.random() * 16); const next = value === "x" ? random : (random & 0x3) | 0x8; return next.toString(16); }); }