import { clsx, type ClassValue } from 'clsx'; export function cn(...inputs: ClassValue[]) { return clsx(inputs); } export function formatDate(date: string | Date): string { const d = new Date(date); const now = new Date(); const diffInHours = (now.getTime() - d.getTime()) / (1000 * 60 * 60); if (diffInHours < 1) { return 'Just now'; } else if (diffInHours < 24) { return `${Math.floor(diffInHours)}h ago`; } else if (diffInHours < 24 * 7) { return `${Math.floor(diffInHours / 24)}d ago`; } else { return d.toLocaleDateString(); } } export function generateId(): string { return Math.random().toString(36).substr(2, 9); } export function truncateText(text: string, maxLength: number): string { if (text.length <= maxLength) return text; return text.substr(0, maxLength) + '...'; } export function extractTitle(content: string): string { // Extract first line or first 50 characters as title const firstLine = content.split('\n')[0]; return truncateText(firstLine || 'New Conversation', 50); } export function isValidEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } export function debounce any>( func: T, wait: number ): (...args: Parameters) => void { let timeout: NodeJS.Timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => func(...args), wait); }; } export function throttle any>( func: T, limit: number ): (...args: Parameters) => void { let inThrottle: boolean; return (...args) => { if (!inThrottle) { func(...args); inThrottle = true; setTimeout(() => (inThrottle = false), limit); } }; } export function copyToClipboard(text: string): Promise { if (navigator.clipboard) { return navigator.clipboard.writeText(text); } else { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { document.execCommand('copy'); document.body.removeChild(textArea); return Promise.resolve(); } catch (err) { document.body.removeChild(textArea); return Promise.reject(err); } } } export function downloadText(content: string, filename: string): void { const element = document.createElement('a'); const file = new Blob([content], { type: 'text/plain' }); element.href = URL.createObjectURL(file); element.download = filename; document.body.appendChild(element); element.click(); document.body.removeChild(element); } export function parseJsonSafely(json: string): T | null { try { return JSON.parse(json); } catch { return null; } } export function getStorageItem(key: string, defaultValue: T): T { try { const item = localStorage.getItem(key); return item ? JSON.parse(item) : defaultValue; } catch { return defaultValue; } } export function setStorageItem(key: string, value: T): void { try { localStorage.setItem(key, JSON.stringify(value)); } catch (error) { console.error('Failed to save to localStorage:', error); } }