//
//  EQUIPMENT_ITEM_RELATIONSHIP_GUIDE.md
//  iSMARTtrain
//
//  Created by Assistant on 11/03/2026.
//

# Equipment-Item Relationship Guide

This guide explains how to complete the integration between Equipment and Item (sessions) models.

## Current Status

✅ **Completed:**
- SessionDialog now has a tabbed interface with "Session" and "Equipment" tabs
- Equipment tab displays all available equipment with checkboxes
- UI for selecting/deselecting equipment is implemented
- Selected equipment IDs are tracked in the dialog state
- Placeholder code is ready for when the relationship exists

❌ **Pending:**
- Item model does not yet have a relationship to Equipment
- Equipment associations are not saved to the database
- Equipment tracking (distance, duration, use count) is not updated

## Step 1: Add Equipment Relationship to Item Model

Edit `Item.swift` and add the equipment relationship:

```swift
@Model
final class Item {
    var timestamp: Date
    var distanceData: AnyCodableMeasurement
    var duration: Double
    var start: Date
    var sport: String
    // ... other properties ...
    
    // Relationship to ISTSport
    var istSport: ISTSport?
    
    // NEW: Relationship to Equipment
    @Relationship(deleteRule: .nullify)
    var equipment: [Equipment] = []
    
    // ... rest of the class ...
}
```

### Explanation:
- `@Relationship(deleteRule: .nullify)` means when equipment is deleted, the Item remains but the relationship is cleared
- `var equipment: [Equipment] = []` creates a many-to-many relationship (one session can use multiple pieces of equipment)

## Step 2: Add Inverse Relationship to Equipment Model

Edit `Equipment.swift` and add the inverse relationship:

```swift
@Model
final class Equipment {
    var timestamp: Date
    var purchased: Date
    var name: String
    // ... other properties ...
    
    // Inverse relationship to User
    var user: User?
    
    // Relationship to Components
    @Relationship(deleteRule: .cascade, inverse: \Component.equipment)
    var components: [Component] = []
    
    // NEW: Inverse relationship to Items
    @Relationship(inverse: \Item.equipment)
    var sessions: [Item] = []
    
    // ... rest of the class ...
}
```

### Explanation:
- The inverse relationship allows Equipment to know which sessions use it
- This is optional but useful for displaying equipment usage history

## Step 3: Update Equipment Code in SessionDialog

Once the relationships are added, update the code in `SessionDialog.swift`:

### In `setupInitialValues()`:
```swift
case .view(let item), .edit(let item):
    // ... other setup code ...
    
    // Load selected equipment
    selectedEquipmentIDs = Set(item.equipment.map { $0.persistentModelID })
```

### In `saveItem()` - Fix the switch cases:
```swift
switch mode {
case .edit(let item), .view(let item):
    // Update existing item (both .edit and .view with isEditingMode = true)
    item.start = start
    // ... other update code ...
    
    // Update equipment associations
    item.equipment = availableEquipment.filter { selectedEquipmentIDs.contains($0.persistentModelID) }
    
case .create:
    // Create new item
    let newItem = try? Item.create(...)
    if let newItem = newItem {
        modelContext.insert(newItem)
        
        // Set equipment associations
        newItem.equipment = availableEquipment.filter { selectedEquipmentIDs.contains($0.persistentModelID) }
    }
}
```

**Important:** The key fix here is that `case .edit(let item), .view(let item):` handles both modes, because when you tap "Edit" in view mode, `isEditingMode` is set to true but the `mode` enum remains `.view(item)`, not `.edit(item)`. This prevents creating duplicate items.

## Step 4: Update Equipment Usage Tracking (Optional but Recommended)

Add a helper function to update equipment usage statistics when a session is saved:

```swift
// In SessionDialog.swift, add this function:
private func updateEquipmentUsage() {
    let sessionDuration = Double(timeToSeconds(timeString))
    let sessionDistance = (Double(distanceString) ?? 0) * 1000 // Convert km to meters
    
    // When editing, first remove old session stats from previously associated equipment
    if case .view(let item) = mode, isEditingMode {
        // Get the old equipment before we change it
        let oldEquipment = item.equipment
        for equipment in oldEquipment {
            equipment.totalDuration -= item.duration
            equipment.totalDistance -= (item.distance?.converted(to: .meters).value ?? 0)
            equipment.useCount -= 1
        }
    } else if case .edit(let item) = mode {
        // Get the old equipment before we change it
        let oldEquipment = item.equipment
        for equipment in oldEquipment {
            equipment.totalDuration -= item.duration
            equipment.totalDistance -= (item.distance?.converted(to: .meters).value ?? 0)
            equipment.useCount -= 1
        }
    }
    
    // Now add new session stats to newly selected equipment
    let selectedEquipment = availableEquipment.filter {
        selectedEquipmentIDs.contains($0.persistentModelID)
    }
    
    for equipment in selectedEquipment {
        equipment.totalDuration += sessionDuration
        equipment.totalDistance += sessionDistance
        equipment.useCount += 1
    }
}
```

Then call it in `saveItem()` before saving:

```swift
private func saveItem() {
    // ... existing code ...
    
    // Update equipment usage statistics
    updateEquipmentUsage()
    
    try? modelContext.save()
}
```

**Important Note:** The equipment usage tracking must be called BEFORE updating the item's equipment array, so it can subtract the old values from the previously associated equipment.

## Step 5: Handle Equipment Stats When Deleting Sessions

When a session is deleted, you need to subtract its stats from the associated equipment. Update the `deleteItem()` function:

```swift
private func deleteItem() {
    if let item = currentItem {
        // Remove equipment usage statistics before deleting
        for equipment in item.equipment {
            equipment.totalDuration -= item.duration
            equipment.totalDistance -= (item.distance?.converted(to: .meters).value ?? 0)
            equipment.useCount -= 1
        }
        
        modelContext.delete(item)
        try? modelContext.save()
    }
}
```

This ensures that when a session is deleted, the equipment's usage statistics are accurately updated by subtracting the deleted session's contribution.

## Step 6: Display Equipment in View Mode (Optional Enhancement)

You can enhance the view mode to show which equipment was used. Add this to the `viewModeContent`:

```swift
private var viewModeContent: some View {
    VStack(alignment: .leading, spacing: 12) {
        // ... existing content ...
        
        // NEW: Show equipment used
        if let item = currentItem, !item.equipment.isEmpty {
            Divider()
            
            VStack(alignment: .leading, spacing: 4) {
                Text("Equipment Used")
                    .font(.subheadline)
                    .fontWeight(.semibold)
                    .foregroundColor(.secondary)
                
                ForEach(item.equipment) { equipment in
                    HStack(spacing: 8) {
                        Image(systemName: equipmentIcon(for: equipment.type))
                            .foregroundColor(.blue)
                            .frame(width: 20)
                        
                        Text(equipment.name)
                            .font(.subheadline)
                        
                        Spacer()
                    }
                }
            }
        }
        
        Spacer()
    }
}
```

## Step 7: Add Equipment Icon Helper

Add this helper function if you haven't already (it's already in the EquipmentRowView, but can be reused):

```swift
private func equipmentIcon(for type: EquipmentType) -> String {
    switch type {
    case .bike:
        return "bicycle"
    case .shoes:
        return "shoe.2"
    case .other:
        return "gear"
    }
}
```

## Equipment Usage Statistics Lifecycle

The equipment usage statistics (`totalDuration`, `totalDistance`, `useCount`) are automatically maintained across the session lifecycle:

1. **Creating a Session:** Stats are added to associated equipment
2. **Editing a Session:** 
   - Old stats are subtracted from previously associated equipment
   - New stats are added to newly associated equipment
   - If duration/distance changed, the difference is reflected
3. **Deleting a Session:** Stats are subtracted from associated equipment

This ensures equipment stats always accurately reflect their actual usage.

## Testing Checklist

After implementing the changes:

1. ✅ Create a new session and assign equipment
2. ✅ Verify equipment is saved with the session
3. ✅ Verify equipment stats (duration, distance, useCount) increase correctly
4. ✅ Edit an existing session and change equipment
5. ✅ Verify equipment associations update correctly
6. ✅ Verify old equipment stats decrease and new equipment stats increase
7. ✅ Delete a session with equipment
8. ✅ Verify equipment stats decrease correctly after deletion
9. ✅ Delete equipment and verify session remains but relationship is cleared
10. ✅ View mode displays associated equipment

## Data Model Relationships Diagram

```
User
  └─ Equipment (one-to-many)
       ├─ Component (one-to-many, bikes only)
       └─ Item/Session (many-to-many)

ISTSport
  └─ Item/Session (one-to-many)

Item/Session
  ├─ ISTSport (many-to-one)
  └─ Equipment (many-to-many)
```

## Notes

- The many-to-many relationship allows:
  - One session to use multiple pieces of equipment (e.g., bike + shoes)
  - One piece of equipment to be used in multiple sessions (tracking total usage)
  
- Equipment usage tracking includes:
  - `totalDuration`: Total time equipment has been used (in seconds)
  - `totalDistance`: Total distance covered with equipment (in meters)
  - `useCount`: Number of times equipment has been used
  
- These statistics can be displayed in the EquipmentListView or EquipmentEditorView to show wear and usage patterns

- **Automatic Stats Management:** Equipment statistics are automatically maintained:
  - ✅ **Creating:** Stats added when session is created with equipment
  - ✅ **Editing:** Old stats removed, new stats added when equipment changes
  - ✅ **Deleting:** Stats removed when session is deleted
  - This ensures stats always accurately reflect actual usage

## Potential Edge Cases to Consider

1. **Negative Stats:** If you're migrating existing data or manually editing the database, equipment stats could become negative. Consider adding validation:
   ```swift
   equipment.useCount = max(0, equipment.useCount - 1)
   equipment.totalDuration = max(0, equipment.totalDuration - item.duration)
   equipment.totalDistance = max(0, equipment.totalDistance - distance)
   ```

2. **Bulk Operations:** If you bulk delete sessions elsewhere in your app (not through SessionDialog), make sure to also update equipment stats there.

3. **Equipment Deletion:** When equipment is deleted, the relationship uses `.nullify`, so sessions remain but lose their equipment reference. The stats are lost with the equipment.

## Migration Considerations

If you already have existing data in your app:

1. SwiftData should handle adding the new relationship automatically
2. Existing sessions will have empty equipment arrays
3. Existing equipment will have empty sessions arrays
4. No data will be lost, only new relationships will be added

However, it's recommended to:
- Test on a development database first
- Consider adding a lightweight migration if needed
- Back up user data before deploying this change
