import { useState, useEffect, useCallback } from 'react'; import { eq } from 'drizzle-orm'; import { useDatabase } from './useDatabase'; import { currentUser, appState } from '../db/schema'; // ─── Types ───────────────────────────────────────────────────────────────────── interface UseThemeModeReturn { isDark: boolean; toggleTheme: () => Promise; setDark: (isDark: boolean) => Promise; loading: boolean; } // ─── Hook ────────────────────────────────────────────────────────────────────── // Reads the dark_mode preference. It first checks the app_state table (key: // "dark_mode") and falls back to system default (false = light). const DARK_MODE_KEY = 'dark_mode'; export function useThemeMode(): UseThemeModeReturn { const { db } = useDatabase(); const [isDark, setIsDark] = useState(false); const [loading, setLoading] = useState(true); // ── Load theme preference ──────────────────────────────────────────────────── const loadTheme = useCallback(async () => { try { const rows = await db .select() .from(appState) .where(eq(appState.key, DARK_MODE_KEY)) .all(); if (rows.length > 0) { setIsDark(rows[0].value === 'true'); } else { // Check current_user table for darkMode field const userRows = await db.select().from(currentUser).limit(1).all(); if (userRows.length > 0) { const userData = userRows[0] as Record; if (typeof userData.darkMode === 'number') { setIsDark(userData.darkMode === 1); } else if (typeof userData.darkMode === 'boolean') { setIsDark(userData.darkMode); } } } } catch (error) { console.error('[useThemeMode] Failed to load theme preference:', error); setIsDark(false); } finally { setLoading(false); } }, [db]); useEffect(() => { loadTheme(); }, [loadTheme]); // ── Toggle theme ───────────────────────────────────────────────────────────── const toggleTheme = useCallback(async () => { const newValue = !isDark; await setDark(newValue); }, [isDark]); // ── Set dark mode explicitly ───────────────────────────────────────────────── const setDark = useCallback( async (dark: boolean) => { try { setIsDark(dark); // Upsert into app_state table await db .insert(appState) .values({ key: DARK_MODE_KEY, value: String(dark) }) .onConflictDoUpdate({ target: appState.key, set: { value: String(dark), updatedAt: new Date().toISOString() }, }) .run(); } catch (error) { console.error('[useThemeMode] Failed to save theme preference:', error); } }, [db], ); return { isDark, toggleTheme, setDark, loading, }; }