import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:trainhub_flutter/core/utils/id_generator.dart'; import 'package:trainhub_flutter/injection.dart'; import 'package:trainhub_flutter/domain/entities/exercise.dart'; import 'package:trainhub_flutter/domain/entities/training_exercise.dart'; import 'package:trainhub_flutter/domain/entities/training_plan.dart'; import 'package:trainhub_flutter/domain/entities/training_section.dart'; import 'package:trainhub_flutter/domain/repositories/exercise_repository.dart'; import 'package:trainhub_flutter/domain/repositories/training_plan_repository.dart'; import 'package:trainhub_flutter/presentation/plan_editor/plan_editor_state.dart'; part 'plan_editor_controller.g.dart'; @riverpod class PlanEditorController extends _$PlanEditorController { late TrainingPlanRepository _planRepo; @override Future build(String planId) async { _planRepo = getIt(); final ExerciseRepository exerciseRepo = getIt(); final plan = await _planRepo.getById(planId); final exercises = await exerciseRepo.getAll(); return PlanEditorState(plan: plan, availableExercises: exercises); } void updatePlanName(String name) { final current = state.valueOrNull; if (current == null) return; state = AsyncValue.data( current.copyWith(plan: current.plan.copyWith(name: name), isDirty: true), ); } void addSection() { final current = state.valueOrNull; if (current == null) return; final newSection = TrainingSectionEntity( id: IdGenerator.generate(), name: 'New Section', ); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith( sections: [...current.plan.sections, newSection], ), isDirty: true, ), ); } void deleteSection(int index) { final current = state.valueOrNull; if (current == null) return; final sections = List.from(current.plan.sections); sections.removeAt(index); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith(sections: sections), isDirty: true, ), ); } void updateSectionName(int sectionIndex, String name) { final current = state.valueOrNull; if (current == null) return; final sections = List.from(current.plan.sections); sections[sectionIndex] = sections[sectionIndex].copyWith(name: name); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith(sections: sections), isDirty: true, ), ); } void addExerciseToSection(int sectionIndex, ExerciseEntity exercise) { final current = state.valueOrNull; if (current == null) return; final sections = List.from(current.plan.sections); final newExercise = TrainingExerciseEntity( instanceId: IdGenerator.generate(), exerciseId: exercise.id, name: exercise.name, ); sections[sectionIndex] = sections[sectionIndex].copyWith( exercises: [...sections[sectionIndex].exercises, newExercise], ); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith(sections: sections), isDirty: true, ), ); } void removeExerciseFromSection(int sectionIndex, int exerciseIndex) { final current = state.valueOrNull; if (current == null) return; final sections = List.from(current.plan.sections); final exercises = List.from( sections[sectionIndex].exercises, ); exercises.removeAt(exerciseIndex); sections[sectionIndex] = sections[sectionIndex].copyWith( exercises: exercises, ); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith(sections: sections), isDirty: true, ), ); } void updateExerciseParams( int sectionIndex, int exerciseIndex, { int? sets, int? value, bool? isTime, int? rest, }) { final current = state.valueOrNull; if (current == null) return; final sections = List.from(current.plan.sections); final exercises = List.from( sections[sectionIndex].exercises, ); exercises[exerciseIndex] = exercises[exerciseIndex].copyWith( sets: sets ?? exercises[exerciseIndex].sets, value: value ?? exercises[exerciseIndex].value, isTime: isTime ?? exercises[exerciseIndex].isTime, rest: rest ?? exercises[exerciseIndex].rest, ); sections[sectionIndex] = sections[sectionIndex].copyWith( exercises: exercises, ); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith(sections: sections), isDirty: true, ), ); } void reorderExercise(int sectionIndex, int oldIndex, int newIndex) { final current = state.valueOrNull; if (current == null) return; final sections = List.from(current.plan.sections); final exercises = List.from( sections[sectionIndex].exercises, ); if (oldIndex < newIndex) newIndex -= 1; final item = exercises.removeAt(oldIndex); exercises.insert(newIndex, item); sections[sectionIndex] = sections[sectionIndex].copyWith( exercises: exercises, ); state = AsyncValue.data( current.copyWith( plan: current.plan.copyWith(sections: sections), isDirty: true, ), ); } Future save() async { final current = state.valueOrNull; if (current == null) return; await _planRepo.update(current.plan); state = AsyncValue.data(current.copyWith(isDirty: false)); } }