// // WorkoutDetailView.swift // Workouts // // Created by rzen on 7/22/25 at 9:54 PM. // // Copyright 2025 Rouslan Zenetl. All Rights Reserved. // import SwiftUI import SwiftData struct WorkoutDetailView: View { let workout: Workout @Environment(\.modelContext) private var modelContext @Environment(\.dismiss) private var dismiss @State private var showingCompletedDialog = false @State private var selectedLog: WorkoutLog? = nil @State private var navigateToExercise = false var body: some View { VStack(alignment: .center, spacing: 8) { if let logs = workout.logs?.sorted(by: { $0.order < $1.order }), !logs.isEmpty { List { ForEach(logs) { log in Button { handleExerciseTap(log) } label: { WorkoutLogCardView(log: log) } .listRowBackground( RoundedRectangle(cornerRadius: 12) .fill(Color.secondary.opacity(0.2)) .padding( EdgeInsets( top: 4, leading: 8, bottom: 4, trailing: 8 ) ) ) } } .listStyle(.carousel) } else { Text("No exercises in this workout") .font(.body) .foregroundStyle(.secondary) .padding() Spacer() } } .navigationDestination(isPresented: $navigateToExercise) { if let selectedLog = selectedLog { ExerciseProgressControlView(log: selectedLog) } } .alert("Exercise Completed", isPresented: $showingCompletedDialog) { Button("Cancel", role: .cancel) { // Do nothing, just dismiss } Button("Restart") { if let log = selectedLog { restartExercise(log) } } Button("One More Set") { if let log = selectedLog { addOneMoreSet(log) } } } message: { Text("This exercise is already completed. What would you like to do?") } } private func handleExerciseTap(_ log: WorkoutLog) { selectedLog = log switch log.status { case .notStarted: // Start from beginning log.currentStateIndex = 0 try? modelContext.save() navigateToExercise = true case .inProgress: // If we're in a rest state, advance to the next set if let currentStateIndex = log.currentStateIndex, isRestState(currentStateIndex) { log.currentStateIndex = currentStateIndex + 1 try? modelContext.save() } // Continue from current (possibly updated) position navigateToExercise = true case .completed: // Show dialog for completed exercise showingCompletedDialog = true default: // Default to not started behavior log.currentStateIndex = 0 try? modelContext.save() navigateToExercise = true } } private func restartExercise(_ log: WorkoutLog) { log.status = .notStarted log.currentStateIndex = 0 log.elapsedSeconds = 0 try? modelContext.save() navigateToExercise = true } private func addOneMoreSet(_ log: WorkoutLog) { // Increment total sets log.sets += 1 // Calculate the state index for the additional set // States: intro(0) → set1(1) → rest1(2) → ... → setN(2N-1) → done(2N) // For the additional set, we want to go to setN+1 which is at index 2N+1 let additionalSetStateIndex = (log.sets * 2) - 1 log.status = .inProgress log.currentStateIndex = additionalSetStateIndex log.elapsedSeconds = 0 try? modelContext.save() navigateToExercise = true } private func isRestState(_ stateIndex: Int) -> Bool { // Rest states are at even indices > 0 return stateIndex > 0 && stateIndex % 2 == 0 } }