# Theme System Documentation

## Tổng quan

Hệ thống theme hỗ trợ **Light Mode**, **Dark Mode** và **System Mode** (tự động theo hệ thống). Theme preference được lưu trong AsyncStorage và tự động khôi phục khi khởi động lại ứng dụng.

## Kiến trúc Theme System

### 1. Theme Provider (`hooks/use-theme-context.tsx`)

Theme Provider là core của hệ thống theme, quản lý state và đồng bộ với system theme.

**Các tính năng chính:**

- Quản lý `themeMode`: `'light' | 'dark' | 'system'`
- Tự động detect system theme thông qua nhiều nguồn:
  - `Appearance.getColorScheme()` - iOS/Android system theme
  - `useColorScheme()` hook từ React Native
  - `Appearance.addChangeListener()` - listen system theme changes
  - `AppState` listener - sync lại khi app active
- Lưu và restore theme preference từ AsyncStorage
- Export ra `colorScheme` cuối cùng: `'light' | 'dark'`

**ThemeContextType:**

```typescript
interface ThemeContextType {
  themeMode: ThemeMode; // User's choice: 'light' | 'dark' | 'system'
  colorScheme: ColorScheme; // Final theme: 'light' | 'dark'
  colors: typeof Colors.light; // Theme colors object
  setThemeMode: (mode: ThemeMode) => Promise<void>;
  getColor: (colorName: ColorName) => string;
  isHydrated: boolean; // AsyncStorage đã load xong
}
```

**Cách hoạt động:**

```typescript
// Xác định colorScheme cuối cùng
const colorScheme: ColorScheme =
  themeMode === "system" ? systemScheme : themeMode;
```

### 2. Colors Configuration (`constants/theme.ts`)

Định nghĩa tất cả colors cho light và dark theme:

```typescript
export const Colors = {
  light: {
    text: "#11181C",
    textSecondary: "#687076",
    background: "#fff",
    backgroundSecondary: "#f5f5f5",
    surface: "#ffffff",
    surfaceSecondary: "#f8f9fa",
    tint: "#0a7ea4",
    primary: "#007AFF",
    secondary: "#5AC8FA",
    success: "#34C759",
    warning: "#ff6600",
    error: "#FF3B30",
    icon: "#687076",
    border: "#C6C6C8",
    separator: "#E5E5E7",
    card: "#ffffff",
    // ... more colors
  },
  dark: {
    text: "#ECEDEE",
    textSecondary: "#8E8E93",
    background: "#000000",
    backgroundSecondary: "#1C1C1E",
    surface: "#1C1C1E",
    surfaceSecondary: "#2C2C2E",
    tint: "#fff",
    primary: "#0A84FF",
    secondary: "#64D2FF",
    success: "#30D158",
    warning: "#ff6600",
    error: "#FF453A",
    icon: "#8E8E93",
    border: "#38383A",
    separator: "#38383A",
    card: "#1C1C1E",
    // ... more colors
  },
};

export type ColorName = keyof typeof Colors.light;
```

### 3. Setup trong App (`app/_layout.tsx`)

Theme Provider phải wrap toàn bộ app:

```tsx
export default function RootLayout() {
  return (
    <I18nProvider>
      <AppThemeProvider>
        <AppContent />
      </AppThemeProvider>
    </I18nProvider>
  );
}

function AppContent() {
  const { colorScheme } = useThemeContext();

  return (
    <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
      <Stack>{/* ... routes */}</Stack>
      <StatusBar style="auto" />
    </ThemeProvider>
  );
}
```

## Cách sử dụng Theme

### 1. useThemeContext (Core Hook)

Hook chính để access theme state:

```tsx
import { useThemeContext } from "@/hooks/use-theme-context";

function MyComponent() {
  const {
    themeMode, // 'light' | 'dark' | 'system'
    colorScheme, // 'light' | 'dark'
    colors, // Colors object
    setThemeMode, // Change theme
    getColor, // Get color by name
    isHydrated, // AsyncStorage loaded
  } = useThemeContext();

  return (
    <View style={{ backgroundColor: colors.background }}>
      <Text style={{ color: colors.text }}>
        Mode: {themeMode}, Scheme: {colorScheme}
      </Text>
    </View>
  );
}
```

### 2. useColorScheme Hook

Alias để lấy colorScheme nhanh:

```tsx
import { useColorScheme } from "@/hooks/use-theme-context";

function MyComponent() {
  const colorScheme = useColorScheme(); // 'light' | 'dark'

  return <Text>Current theme: {colorScheme}</Text>;
}
```

**⚠️ Lưu ý:** `useColorScheme` từ `use-theme-context.tsx`, KHÔNG phải từ `react-native`.

### 3. useThemeColor Hook

Override colors cho specific themes:

```tsx
import { useThemeColor } from "@/hooks/use-theme-color";

function MyComponent() {
  // Với override
  const backgroundColor = useThemeColor(
    { light: "#ffffff", dark: "#1C1C1E" },
    "surface"
  );

  // Không override, dùng color từ theme
  const textColor = useThemeColor({}, "text");

  return (
    <View style={{ backgroundColor }}>
      <Text style={{ color: textColor }}>Text</Text>
    </View>
  );
}
```

**Cách hoạt động:**

```typescript
// Ưu tiên props override trước, sau đó mới dùng Colors
const colorFromProps = props[colorScheme];
return colorFromProps || Colors[colorScheme][colorName];
```

### 4. useAppTheme Hook (Recommended)

Hook tiện lợi với pre-built styles và utilities:

```tsx
import { useAppTheme } from "@/hooks/use-app-theme";

function MyComponent() {
  const { colors, styles, utils } = useAppTheme();

  return (
    <View style={styles.container}>
      <TouchableOpacity style={styles.primaryButton}>
        <Text style={styles.primaryButtonText}>Primary Button</Text>
      </TouchableOpacity>

      <View style={styles.card}>
        <Text style={{ color: colors.text }}>
          Theme is {utils.isDark ? "Dark" : "Light"}
        </Text>
      </View>

      <View
        style={{
          backgroundColor: utils.getOpacityColor("primary", 0.1),
        }}
      >
        <Text>Transparent background</Text>
      </View>
    </View>
  );
}
```

### 5. Themed Components

**ThemedView** và **ThemedText** - Tự động apply theme colors:

```tsx
import { ThemedText } from "@/components/themed-text";
import { ThemedView } from "@/components/themed-view";

function MyComponent() {
  return (
    <ThemedView>
      <ThemedText type="title">Title Text</ThemedText>
      <ThemedText type="subtitle">Subtitle</ThemedText>
      <ThemedText type="default">Regular Text</ThemedText>
      <ThemedText type="link">Link Text</ThemedText>

      {/* Override với custom colors */}
      <ThemedText lightColor="#000000" darkColor="#FFFFFF">
        Custom colored text
      </ThemedText>
    </ThemedView>
  );
}
```

**ThemedText types:**

- `default` - 16px regular
- `title` - 32px bold
- `subtitle` - 20px bold
- `defaultSemiBold` - 16px semibold
- `link` - 16px với color #0a7ea4

### 6. Theme Toggle Component

Component có sẵn để user chọn theme:

```tsx
import { ThemeToggle } from "@/components/theme-toggle";

function SettingsScreen() {
  return (
    <View>
      <ThemeToggle />
    </View>
  );
}
```

Component này hiển thị 3 options: Light, Dark, System với icons và labels đa ngôn ngữ.

## Available Styles từ useAppTheme

```typescript
const { styles } = useAppTheme();

// Container styles
styles.container; // Flex 1 container với background
styles.surface; // Surface với padding 16, borderRadius 12
styles.card; // Card với shadow, elevation

// Button styles
styles.primaryButton; // Primary button với colors.primary
styles.secondaryButton; // Secondary button với border
styles.primaryButtonText; // White text cho primary button
styles.secondaryButtonText; // Theme text cho secondary button

// Input styles
styles.textInput; // Text input với border, padding

// Status styles
styles.successContainer; // Success background với border
styles.warningContainer; // Warning background với border
styles.errorContainer; // Error background với border

// Utility
styles.separator; // 1px line separator
```

## Theme Utilities

```typescript
const { utils } = useAppTheme();

// Check theme
utils.isDark; // boolean - true nếu dark mode
utils.isLight; // boolean - true nếu light mode

// Toggle theme (ignores system mode)
utils.toggleTheme(); // Switch giữa light ↔ dark

// Get color với opacity
utils.getOpacityColor("primary", 0.1); // rgba(0, 122, 255, 0.1)
```

## Luồng hoạt động của Theme System

```
1. App khởi động
   └─→ ThemeProvider mount
       ├─→ Load saved themeMode từ AsyncStorage ('light'/'dark'/'system')
       ├─→ Detect systemScheme từ OS
       │   ├─→ Appearance.getColorScheme()
       │   ├─→ useColorScheme() hook
       │   └─→ Appearance.addChangeListener()
       └─→ Tính toán colorScheme cuối cùng
           └─→ themeMode === 'system' ? systemScheme : themeMode

2. User thay đổi system theme
   └─→ Appearance listener fire
       └─→ Update systemScheme state
           └─→ Nếu themeMode === 'system'
               └─→ colorScheme tự động update
                   └─→ Components re-render với colors mới

3. User chọn theme trong app
   └─→ setThemeMode('light'/'dark'/'system')
       ├─→ Update themeMode state
       ├─→ Save vào AsyncStorage
       └─→ colorScheme update
           └─→ Components re-render

4. App về foreground
   └─→ AppState listener fire
       └─→ Sync lại systemScheme (phòng user đổi system theme khi app background)
```

## Storage

Theme preference được lưu với key: `'theme_mode'`

```typescript
// Tự động xử lý bởi ThemeProvider
await setStorageItem("theme_mode", "light" | "dark" | "system");
const savedMode = await getStorageItem("theme_mode");
```

## Best Practices

1. **Sử dụng hooks đúng context:**

   - `useThemeContext()` - Khi cần full control (themeMode, setThemeMode)
   - `useColorScheme()` - Chỉ cần biết light/dark
   - `useAppTheme()` - Recommended cho UI components (có styles + utils)
   - `useThemeColor()` - Khi cần override colors

2. **Sử dụng Themed Components:**

   ```tsx
   // Good ✅
   <ThemedView>
     <ThemedText>Hello</ThemedText>
   </ThemedView>;

   // Also good ✅
   const { colors } = useAppTheme();
   <View style={{ backgroundColor: colors.background }}>
     <Text style={{ color: colors.text }}>Hello</Text>
   </View>;
   ```

3. **Tận dụng pre-built styles:**

   ```tsx
   // Good ✅
   const { styles } = useAppTheme();
   <TouchableOpacity style={styles.primaryButton}>

   // Less good ❌
   <TouchableOpacity style={{
     backgroundColor: colors.primary,
     paddingVertical: 14,
     borderRadius: 12
   }}>
   ```

4. **Sử dụng opacity colors:**

   ```tsx
   const { utils } = useAppTheme();
   <View
     style={{
       backgroundColor: utils.getOpacityColor("primary", 0.1),
     }}
   />;
   ```

5. **Check theme correctly:**

   ```tsx
   // Good ✅
   const { utils } = useAppTheme();
   if (utils.isDark) { ... }

   // Also good ✅
   const { colorScheme } = useThemeContext();
   if (colorScheme === 'dark') { ... }
   ```

## Troubleshooting

### Theme không được lưu

- Kiểm tra AsyncStorage permissions
- Check logs trong console: `[Theme] Failed to save theme mode:`

### Flash màu sắc khi khởi động

- ThemeProvider đã xử lý với `isHydrated` state
- Chờ AsyncStorage load xong trước khi render

### System theme không update

- Check Appearance listener đã register: `[Theme] Registering appearance listener`
- Check logs: `[Theme] System theme changed to: ...`
- iOS: Restart app sau khi đổi system theme
- Android: Cần `expo-system-ui` plugin trong `app.json`

### Colors không đúng

- Đảm bảo app wrapped trong `<AppThemeProvider>`
- Check `colorScheme` trong console logs
- Verify Colors object trong `constants/theme.ts`

## Migration Guide

Nếu đang dùng old theme system:

```tsx
// Old ❌
import { useColorScheme } from "react-native";
const colorScheme = useColorScheme();
const backgroundColor = colorScheme === "dark" ? "#000" : "#fff";

// New ✅
import { useAppTheme } from "@/hooks/use-app-theme";
const { colors } = useAppTheme();
const backgroundColor = colors.background;
```

```tsx
// Old ❌
const [theme, setTheme] = useState("light");

// New ✅
import { useThemeContext } from "@/hooks/use-theme-context";
const { themeMode, setThemeMode } = useThemeContext();
```

## Debug Logs

Enable logs để debug theme issues:

```tsx
// Trong use-theme-context.tsx, uncomment các dòng:
console.log("[Theme] Appearance.getColorScheme():", scheme);
console.log("[Theme] System theme changed to:", newScheme);
console.log("[Theme] Mode:", themeMode);
console.log("[Theme] Derived colorScheme:", colorScheme);
```

```tsx
// Trong use-theme-color.ts:
console.log("Detected theme:", theme); // Đã có sẵn
```

```tsx
// Trong _layout.tsx:
console.log("Color Scheme: ", colorScheme); // Đã có sẵn
```
