import { ref, computed } from "vue"; import { useAuthSession } from "./useAuthSession"; export interface CharacterSessionItem { id: string; userId: number | null; tempToken: string | null; cardId: number | null; title: string; modelId: number | null; lastActiveAt: string; expiresAt: string | null; deletedAt: string | null; createdAt: string; updatedAt: string; } export function useCharacterSessions(cardSlug: string) { const auth = useAuthSession(); const sessions = ref([]); const currentSessionId = ref(null); const loading = ref(false); const initialized = ref(false); const currentSession = computed(() => sessions.value.find((s) => s.id === currentSessionId.value) ?? null, ); async function fetchSessions() { loading.value = true; try { const res = await $fetch<{ code: number; data: { list: CharacterSessionItem[] } }>( `/api/characters/${cardSlug}/sessions`, ); sessions.value = res.data?.list ?? []; } catch { sessions.value = []; } finally { loading.value = false; } } async function createSession(): Promise { try { const res = await $fetch<{ code: number; data: { session: CharacterSessionItem } }>( `/api/characters/${cardSlug}/sessions`, { method: "POST" }, ); const session = res.data?.session; if (session) { sessions.value.unshift(session); } return session ?? null; } catch { return null; } } async function newSession(): Promise { const latest = sessions.value[0]; if (latest && latest.lastActiveAt === latest.createdAt) { currentSessionId.value = latest.id; return latest; } const session = await createSession(); if (session) { currentSessionId.value = session.id; } return session; } async function selectSession(id: string) { currentSessionId.value = id; } async function renameSession(id: string, title: string) { try { await $fetch(`/api/characters/${cardSlug}/sessions/${id}`, { method: "PUT", body: { title }, }); const s = sessions.value.find((x) => x.id === id); if (s) s.title = title; } catch { } } async function deleteSession(id: string) { try { await $fetch(`/api/characters/${cardSlug}/sessions/${id}`, { method: "DELETE" }); sessions.value = sessions.value.filter((s) => s.id !== id); if (currentSessionId.value === id) { if (sessions.value.length > 0) { currentSessionId.value = sessions.value[0]?.id ?? null; } else { const session = await createSession(); if (session) currentSessionId.value = session.id; else currentSessionId.value = null; } } } catch { } } async function updateModelConfig(id: string, modelId: number | null) { try { await $fetch(`/api/characters/${cardSlug}/sessions/${id}/config`, { method: "PUT", body: { modelId }, }); const s = sessions.value.find((x) => x.id === id); if (s) s.modelId = modelId; } catch { } } function touchSessionOrder(id: string) { const idx = sessions.value.findIndex((s) => s.id === id); if (idx > 0) { const [s] = sessions.value.splice(idx, 1); if (s) { s.lastActiveAt = new Date().toISOString(); sessions.value.unshift(s); } } else if (idx === 0 && sessions.value[0]) { sessions.value[0].lastActiveAt = new Date().toISOString(); } } async function init() { if (initialized.value) return; await auth.refresh(); await fetchSessions(); if (sessions.value.length === 0) { await newSession(); } else { currentSessionId.value = sessions.value[0]?.id ?? null; } initialized.value = true; } return { sessions, currentSessionId, currentSession, loading, initialized, fetchSessions, createSession, newSession, selectSession, renameSession, deleteSession, updateModelConfig, touchSessionOrder, init, }; }