import React, { createContext, useCallback, useContext, useEffect, useState } from "react"; import { useColorScheme } from "react-native"; import * as SecureStore from "expo-secure-store"; const THEME_KEY = "pailot_theme"; type ThemeMode = "light" | "dark" | "system"; export interface ThemeColors { bg: string; bgSecondary: string; bgTertiary: string; text: string; textSecondary: string; textMuted: string; border: string; accent: string; accentBg: string; danger: string; } const darkColors: ThemeColors = { bg: "#0A0A0F", bgSecondary: "#14141F", bgTertiary: "#1E1E2E", text: "#E8E8F0", textSecondary: "#9898B0", textMuted: "#5A5A78", border: "#2E2E45", accent: "#4A9EFF", accentBg: "#4A9EFF18", danger: "#FF3B30", }; const lightColors: ThemeColors = { bg: "#FFFFFF", bgSecondary: "#F5F5F7", bgTertiary: "#EEEEF0", text: "#1C1C1E", textSecondary: "#636366", textMuted: "#AEAEB2", border: "#D1D1D6", accent: "#007AFF", accentBg: "#007AFF14", danger: "#FF3B30", }; interface ThemeContextValue { mode: ThemeMode; isDark: boolean; colors: ThemeColors; setMode: (mode: ThemeMode) => void; cycleMode: () => void; } const ThemeContext = createContext(null); export function ThemeProvider({ children }: { children: React.ReactNode }) { const systemScheme = useColorScheme(); const [mode, setModeState] = useState("dark"); useEffect(() => { SecureStore.getItemAsync(THEME_KEY).then((stored) => { if (stored === "light" || stored === "dark" || stored === "system") { setModeState(stored); } }); }, []); const setMode = useCallback((m: ThemeMode) => { setModeState(m); SecureStore.setItemAsync(THEME_KEY, m); }, []); const cycleMode = useCallback(() => { setModeState((prev) => { const next = prev === "dark" ? "light" : prev === "light" ? "system" : "dark"; SecureStore.setItemAsync(THEME_KEY, next); return next; }); }, []); const isDark = mode === "dark" || (mode === "system" && systemScheme !== "light"); const colors = isDark ? darkColors : lightColors; return ( {children} ); } export function useTheme() { const ctx = useContext(ThemeContext); if (!ctx) throw new Error("useTheme must be used within ThemeProvider"); return ctx; }