import { ref } from 'vue' import { apiCall } from '@/api' export interface HistoryItem { id: string query: string title: string chat_state: string | null mode: string | null pinned: boolean created_at: string | null updated_at: string | null } export function useSearchHistory() { const history = ref([]) const loading = ref(false) const HISTORY_HOURS = 2 // Keep last 2 hours of history async function loadHistory() { loading.value = true try { const result = await apiCall('get_search_history', { limit: 50 }) const allHistory = Array.isArray(result) ? result : [] // Filter to last 2 hours (keep pinned items regardless of age) const cutoffTime = Date.now() - (HISTORY_HOURS * 60 * 60 * 1000) history.value = allHistory.filter((item: HistoryItem) => { if (item.pinned) return true // Always keep pinned items if (!item.updated_at) return false const itemTime = new Date(item.updated_at).getTime() return itemTime >= cutoffTime }) // Clean up old unpinned items from database cleanupOldHistory(cutoffTime) } catch (e) { console.error('Failed to load history:', e) } finally { loading.value = false } } async function cleanupOldHistory(cutoffTime: number) { try { const result = await apiCall('get_search_history', { limit: 100 }) const allHistory = Array.isArray(result) ? result : [] for (const item of allHistory) { if (item.pinned) continue if (!item.updated_at) continue const itemTime = new Date(item.updated_at).getTime() if (itemTime < cutoffTime) { await apiCall('delete_search_history', { id: item.id }) } } } catch (e) { console.error('Failed to cleanup old history:', e) } } async function saveToHistory(query: string, chatState: string, mode: string) { const id = `h_${Date.now()}_${Math.random().toString(36).slice(2, 8)}` try { await apiCall('save_search_history', { id, query, title: query, chatState, mode, }) await loadHistory() } catch (e) { console.error('Failed to save history:', e) } } async function renameHistory(id: string, title: string) { try { await apiCall('rename_search_history', { id, title }) await loadHistory() } catch (e) { console.error('Failed to rename history:', e) } } async function pinHistory(id: string, pinned: boolean) { try { await apiCall('pin_search_history', { id, pinned }) await loadHistory() } catch (e) { console.error('Failed to pin history:', e) } } async function deleteHistory(id: string) { try { await apiCall('delete_search_history', { id }) await loadHistory() } catch (e) { console.error('Failed to delete history:', e) } } function restoreFromHistory(item: HistoryItem): any[] | null { if (!item.chat_state) return null try { return JSON.parse(item.chat_state) } catch { return null } } return { history, loading, loadHistory, saveToHistory, renameHistory, pinHistory, deleteHistory, restoreFromHistory, } } export interface BookmarkItem { id: number label: string history_id: string | null created_at: string | null } export function useBookmarks() { const bookmarks = ref([]) async function loadBookmarks() { try { const result = await apiCall('get_bookmarks', {}) bookmarks.value = Array.isArray(result) ? result : [] } catch (e) { console.error('Failed to load bookmarks:', e) } } async function saveBookmark(label: string, historyId?: string) { try { await apiCall('save_bookmark', { label, historyId: historyId || null }) await loadBookmarks() } catch (e) { console.error('Failed to save bookmark:', e) } } async function deleteBookmark(id: number) { try { await apiCall('delete_bookmark', { id }) await loadBookmarks() } catch (e) { console.error('Failed to delete bookmark:', e) } } return { bookmarks, loadBookmarks, saveBookmark, deleteBookmark, } }