// // ExerciseAddEditView.swift // Workouts // // Created by rzen on 7/15/25 at 7:12 AM. // // Copyright 2025 Rouslan Zenetl. All Rights Reserved. // import SwiftUI import SwiftData struct ExerciseAddEditView: View { @Environment(SyncEngine.self) private var sync @Environment(\.dismiss) private var dismiss @State private var showingExercisePicker = false // The exercise entity provides initial values (read-only). let exercise: Exercise // The parent split is needed to rebuild and save the SplitDocument. let split: Split // Local editable state @State private var exerciseName: String @State private var originalWeight: Int @State private var loadType: LoadType @State private var minutes: Int @State private var seconds: Int @State private var weightTens: Int @State private var weightOnes: Int @State private var reps: Int @State private var sets: Int @State private var weightReminderWeeks: Int @State private var weightLastUpdated: Date? init(exercise: Exercise, split: Split) { self.exercise = exercise self.split = split let w = exercise.weight _exerciseName = State(initialValue: exercise.name) _originalWeight = State(initialValue: w) _loadType = State(initialValue: exercise.loadTypeEnum) _minutes = State(initialValue: exercise.durationMinutes) _seconds = State(initialValue: exercise.durationSeconds) _weightTens = State(initialValue: (w / 10) * 10) _weightOnes = State(initialValue: w % 10) _reps = State(initialValue: exercise.reps) _sets = State(initialValue: exercise.sets) _weightReminderWeeks = State(initialValue: exercise.weightReminderTimeIntervalWeeks) _weightLastUpdated = State(initialValue: exercise.weightLastUpdated) } var body: some View { NavigationStack { Form { Section(header: Text("Exercise")) { if exerciseName.isEmpty { Button(action: { showingExercisePicker = true }) { HStack { Text("Select Exercise") Spacer() Image(systemName: "chevron.right") .foregroundColor(.gray) } } } else { ListItem(title: exerciseName) } } Section(header: Text("Sets/Reps")) { HStack(alignment: .bottom) { VStack(alignment: .center) { Text("Sets") Picker("", selection: $sets) { ForEach(0..<20) { s in Text("\(s)").tag(s) } } .frame(height: 100) .pickerStyle(.wheel) } VStack(alignment: .center) { Text("Reps") Picker("", selection: $reps) { ForEach(0..<100) { r in Text("\(r)").tag(r) } } .frame(height: 100) .pickerStyle(.wheel) } } } Section( header: Text("Load Type"), footer: Text("For bodyweight exercises choose None. For resistance or weight training select Weight. For exercises that are time oriented (like plank or meditation) select Time.") ) { Picker("", selection: $loadType) { ForEach(LoadType.allCases, id: \.self) { load in Text(load.name) .tag(load) } } .pickerStyle(.segmented) } if loadType == .weight { Section(header: Text("Weight")) { HStack { Picker("", selection: $weightTens) { ForEach(0..<100) { lbs in Text("\(lbs * 10)").tag(lbs * 10) } } .frame(height: 100) .pickerStyle(.wheel) Picker("", selection: $weightOnes) { ForEach(0..<10) { lbs in Text("\(lbs)").tag(lbs) } } .frame(height: 100) .pickerStyle(.wheel) Text("lbs") } } } if loadType == .duration { Section(header: Text("Duration")) { HStack { Picker("Minutes", selection: $minutes) { ForEach(0..<60) { minute in Text("\(minute) min").tag(minute) } } .pickerStyle(.wheel) Picker("Seconds", selection: $seconds) { ForEach(0..<60) { second in Text("\(second) sec").tag(second) } } .pickerStyle(.wheel) } } } Section(header: Text("Weight Increase")) { HStack { Text("Remind every \(weightReminderWeeks) weeks") Spacer() Stepper("", value: $weightReminderWeeks, in: 0...366) } if let lastUpdated = weightLastUpdated { Text("Last weight change \(Date().humanTimeInterval(to: lastUpdated)) ago") } } } .sheet(isPresented: $showingExercisePicker) { ExercisePickerView { exerciseNames in exerciseName = exerciseNames.first ?? "Unnamed" } } .navigationTitle(exerciseName.isEmpty ? "New Exercise" : exerciseName) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Cancel") { dismiss() } } ToolbarItem(placement: .navigationBarTrailing) { Button("Save") { saveExercise() dismiss() } } } } } private func saveExercise() { let newWeight = weightTens + weightOnes let updatedWeightDate: Date? = newWeight != originalWeight ? Date() : weightLastUpdated let durationSecs = minutes * 60 + seconds var doc = SplitDocument(from: split) if let idx = doc.exercises.firstIndex(where: { $0.id == exercise.id }) { doc.exercises[idx].name = exerciseName doc.exercises[idx].sets = sets doc.exercises[idx].reps = reps doc.exercises[idx].weight = newWeight doc.exercises[idx].loadType = loadType.rawValue doc.exercises[idx].durationSeconds = durationSecs doc.exercises[idx].weightLastUpdated = updatedWeightDate doc.exercises[idx].weightReminderWeeks = weightReminderWeeks } doc.updatedAt = Date() Task { await sync.save(split: doc) } } }