# Tooltip System Architecture

## Overview

The contextual tooltip system provides a user-friendly way to guide users through their first experiences in the BaoLife app. Tooltips appear once per user, are persisted across app sessions, and integrate seamlessly with the existing design system.

## Component Structure

```
TooltipSystem/
├── TooltipManager.swift          # State management & persistence
├── TooltipView.swift              # UI components & modifiers
├── TooltipUsageExamples.swift    # Integration examples
├── TooltipDemoView.swift         # Testing & development
└── TOOLTIP_ARCHITECTURE.md       # This file
```

## Core Components

### 1. TooltipManager (State Management)

**Purpose**: Central manager for tooltip state and persistence

**Key Features**:
- Tracks which tooltips have been seen
- Persists state to UserDefaults
- Manages active tooltip display
- Optional WebSocket integration for analytics
- Thread-safe with @Published properties

**Public API**:
```swift
class TooltipManager: ObservableObject {
    @Published var activeTooltip: TooltipData?

    func showTooltipIfNeeded(_ id: String, title: String, message: String, position: TooltipPosition)
    func dismissTooltip()
    func hasSeenTooltip(_ id: String) -> Bool
    func resetAllTooltips()
    func resetTooltip(_ id: String)
}
```

**Usage Pattern**:
```swift
// As StateObject (local)
@StateObject private var tooltipManager = TooltipManager()

// As EnvironmentObject (app-wide)
@EnvironmentObject var tooltipManager: TooltipManager
```

### 2. TooltipView (UI Components)

**Components**:
- `TooltipView`: Main card with title, message, and buttons
- `TooltipArrow`: Triangle pointer to target element
- `TooltipModifier`: ViewModifier for easy integration
- View extension: `.tooltip()` modifier

**Design Features**:
- Uses AppColors design system
- Follows AppTypography conventions
- Respects AppSpacing guidelines
- Spring animations for smooth appearance
- Shadow for visual depth
- Dismissible via X button or "Got it" button

**Positioning**:
- `.top`: Tooltip above element, arrow points down
- `.bottom`: Tooltip below element, arrow points up
- `.leading`: Tooltip left of element, arrow points right
- `.trailing`: Tooltip right of element, arrow points left

### 3. Data Models

**TooltipData**:
```swift
struct TooltipData: Identifiable {
    let id: String          // Unique identifier
    let title: String       // Bold headline
    let message: String     // Description text
    let position: TooltipPosition
}
```

**TooltipPosition**:
```swift
enum TooltipPosition {
    case top, bottom, leading, trailing
}
```

**TooltipTrigger**:
```swift
enum TooltipTrigger {
    case onAppear    // Show when view appears
    case onTap       // Show when user taps
    case manual      // Programmatic control
}
```

## Integration Patterns

### Pattern 1: Automatic on First View

```swift
Text("Feature")
    .tooltip(
        manager: tooltipManager,
        id: "feature_intro",
        title: "New Feature",
        message: "Description of the feature",
        position: .bottom,
        trigger: .onAppear
    )
```

### Pattern 2: Conditional Manual Trigger

```swift
.onAppear {
    if someCondition {
        tooltipManager.showTooltipIfNeeded(
            "contextual_help",
            title: "Help",
            message: "Contextual message",
            position: .top
        )
    }
}
```

### Pattern 3: User Action Triggered

```swift
Button("Action") { /* ... */ }
    .tooltip(
        manager: tooltipManager,
        id: "action_help",
        title: "Action",
        message: "What this action does",
        position: .bottom,
        trigger: .onTap
    )
```

### Pattern 4: State Change Triggered

```swift
.onChange(of: webSocketService.person.calcEnergy) { newEnergy in
    if newEnergy < 10 && !tooltipManager.hasSeenTooltip("low_energy") {
        tooltipManager.showTooltipIfNeeded(
            "low_energy",
            title: "Low Energy",
            message: "Refill with diamonds or wait",
            position: .bottom
        )
    }
}
```

## Display Requirements

Every view using tooltips must include the overlay:

```swift
// Tooltip overlay (required)
if let tooltip = tooltipManager.activeTooltip {
    TooltipView(tooltip: tooltip) {
        tooltipManager.dismissTooltip()
    }
    .transition(.scale.combined(with: .opacity))
    .zIndex(100)
}
```

**Optional**: Add dimmed background for focus:

```swift
if let tooltip = tooltipManager.activeTooltip {
    Color.black.opacity(0.4)
        .ignoresSafeArea()
        .onTapGesture {
            tooltipManager.dismissTooltip()
        }

    TooltipView(tooltip: tooltip) {
        tooltipManager.dismissTooltip()
    }
    .transition(.scale.combined(with: .opacity))
    .zIndex(100)
}
```

## Persistence Strategy

**Storage**: UserDefaults with key `"tooltipsSeen"`

**Format**: Array of String IDs

**Behavior**:
- Loaded on TooltipManager initialization
- Saved immediately when tooltip dismissed
- Persists across app sessions
- Not synchronized across devices

**Testing**: Use `resetAllTooltips()` to clear state

## WebSocket Integration

**Optional Analytics**:

When TooltipManager is initialized with WebSocketService:
```swift
let manager = TooltipManager(webSocketService: webSocketService)
```

On tooltip dismissal, sends:
```json
{
    "type": "tooltipSeen",
    "tooltipId": "tooltip_identifier"
}
```

This allows backend tracking of user onboarding progress.

## Best Practices

### ID Naming Convention

Use descriptive, hierarchical IDs:
- `{feature}_{action}_{context}`
- Examples:
  - `energy_bar_first_low`
  - `activities_tab_first_visit`
  - `dating_relationship_unlock`
  - `home_character_intro`

### Message Guidelines

1. **Keep it concise**: 1-2 sentences maximum
2. **Focus on value**: What can the user do?
3. **Action-oriented**: Tell them what to do next
4. **Friendly tone**: Conversational, not technical

**Good Example**:
```
Title: "Low Energy"
Message: "Out of energy? Tap here to refill with diamonds or wait for natural regeneration."
```

**Bad Example**:
```
Title: "Energy System"
Message: "The energy system is a core mechanic that governs the rate at which you can perform actions. It depletes with each action and regenerates over time or can be replenished using premium currency."
```

### Positioning Logic

- **Header elements**: `.bottom`
- **Footer/tab bar**: `.top`
- **Left sidebar**: `.trailing`
- **Right sidebar**: `.leading`
- **Center content**: Use context (usually `.bottom`)

### Animation Guidelines

Always use spring animations:
```swift
.transition(.scale.combined(with: .opacity))
```

Apply to both show and dismiss.

### Performance Considerations

1. **Lazy loading**: Don't create tooltips for views not yet visible
2. **Memory**: Only one tooltip active at a time
3. **Persistence**: UserDefaults is fast enough for this use case
4. **Weak reference**: WebSocketService uses weak reference to prevent retain cycles

## Testing

### Interactive Testing

Run `TooltipDemoView` to test:
- All four position types
- Long message handling
- Dismiss interactions
- Persistence (reset and retry)
- Multiple tooltips in sequence

### Unit Test Coverage

Key test cases:
1. Tooltip shown only once per ID
2. `hasSeenTooltip()` returns correct state
3. Persistence across manager instances
4. `resetAllTooltips()` clears state
5. `activeTooltip` updates correctly
6. WebSocket message sent (if enabled)

### Debug Commands

For development builds:
```swift
#if DEBUG
Button("Reset Tooltips") {
    tooltipManager.resetAllTooltips()
}
#endif
```

## Future Enhancements

Potential improvements (not in MVP):

1. **Advanced Positioning**: GeometryReader for precise placement
2. **Tooltip Sequences**: Built-in support for guided tours
3. **Priority System**: Queue multiple tooltips with priority
4. **Delay Configuration**: Customizable appearance delays
5. **Gesture Tutorials**: Swipe/pinch gesture overlays
6. **A/B Testing**: Server-controlled tooltip content
7. **Analytics Dashboard**: Track completion rates
8. **Accessibility**: VoiceOver announcements
9. **Animations**: Custom entrance/exit animations
10. **Theming**: Support for different visual styles

## Migration Path

When ready to integrate tooltips app-wide:

1. Add TooltipManager to App struct as EnvironmentObject
2. Inject into ContentView
3. Add tooltips to key features one at a time
4. Test each integration
5. Monitor analytics (if enabled)
6. Iterate based on user feedback

## File Sizes

- TooltipManager.swift: 4.3 KB (152 lines)
- TooltipView.swift: 9.8 KB (320+ lines with previews)
- TooltipUsageExamples.swift: 9.2 KB (reference only)
- TooltipDemoView.swift: 5.9 KB (testing tool)

**Total System Size**: ~30 KB of code
