import { ref } from 'vue' import { getApiBase } from '@/api/config' export interface SearchSession { id: string title: string mode: 'keyword' | 'visual' | 'people' | 'agent' message_count: number created_at: string updated_at: string } export interface SearchMessage { id: string session_id: string role: 'user' | 'assistant' content: string results: string mode: string created_at: string } export function useSearchSession() { const sessions = ref([]) const currentSession = ref(null) const messages = ref([]) const loading = ref(false) const error = ref(null) function getAuthHeaders(): Record { const stored = localStorage.getItem('mb_admin_token') if (stored) { try { const data = JSON.parse(stored) if (new Date(data.expires_at) > new Date()) { return { 'Authorization': `Bearer ${data.token}` } } } catch {} } return {} } async function loadSessions() { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions`, { headers: getAuthHeaders() }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) const data = await resp.json() sessions.value = data.sessions || [] } catch (e: any) { error.value = e.message || 'Failed to load sessions' } finally { loading.value = false } } async function createSession(title?: string, mode?: string) { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...getAuthHeaders() }, body: JSON.stringify({ title: title || '未命名搜尋', mode: mode || 'keyword' }) }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) const data = await resp.json() await loadSessions() return data.session } catch (e: any) { error.value = e.message || 'Failed to create session' return null } finally { loading.value = false } } async function renameSession(id: string, title: string) { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', ...getAuthHeaders() }, body: JSON.stringify({ title }) }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) await loadSessions() if (currentSession.value?.id === id) { currentSession.value.title = title } } catch (e: any) { error.value = e.message || 'Failed to rename session' } finally { loading.value = false } } async function deleteSession(id: string) { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) if (currentSession.value?.id === id) { currentSession.value = null messages.value = [] } await loadSessions() } catch (e: any) { error.value = e.message || 'Failed to delete session' } finally { loading.value = false } } async function loadMessages(sessionId: string) { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions/${sessionId}/messages`, { headers: getAuthHeaders() }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) const data = await resp.json() messages.value = data.messages || [] } catch (e: any) { error.value = e.message || 'Failed to load messages' } finally { loading.value = false } } async function saveMessage(sessionId: string, message: { role: string; content: string; mode?: string; results?: any }) { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions/${sessionId}/messages`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...getAuthHeaders() }, body: JSON.stringify({ role: message.role, content: message.content, mode: message.mode || 'keyword', results: message.results ? JSON.stringify(message.results) : '' }) }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) const data = await resp.json() await loadMessages(sessionId) await loadSessions() return data.message } catch (e: any) { error.value = e.message || 'Failed to save message' return null } finally { loading.value = false } } async function updateMessage(sessionId: string, msgId: string, update: { role?: string; content?: string; results?: any }) { loading.value = true error.value = null try { const base = getApiBase() const resp = await fetch(`${base}/api/v2/search-sessions/${sessionId}/messages/${msgId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', ...getAuthHeaders() }, body: JSON.stringify({ ...update, results: update.results ? JSON.stringify(update.results) : undefined }) }) if (!resp.ok) throw new Error(`HTTP ${resp.status}`) await loadMessages(sessionId) } catch (e: any) { error.value = e.message || 'Failed to update message' } finally { loading.value = false } } function setCurrentSession(session: SearchSession | null) { currentSession.value = session if (session) { loadMessages(session.id) } else { messages.value = [] } } return { sessions, currentSession, messages, loading, error, loadSessions, createSession, renameSession, deleteSession, loadMessages, saveMessage, updateMessage, setCurrentSession } }