import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:latlong2/latlong.dart'; import '../models/experience_models.dart'; final experienceControllerProvider = NotifierProvider( ExperienceController.new, ); class ExperienceState { const ExperienceState({ required this.experiences, required this.selectedExperienceId, required this.filterEmotion, required this.profile, }); final List experiences; final String? selectedExperienceId; final ExperienceEmotion? filterEmotion; final ExperienceAuthor profile; List get visibleExperiences { final emotion = filterEmotion; if (emotion == null) { return experiences; } return experiences.where((item) => item.emotion == emotion).toList(); } PlaceExperience? get selectedExperience { for (final experience in experiences) { if (experience.id == selectedExperienceId) { return experience; } } return visibleExperiences.isEmpty ? null : visibleExperiences.first; } ExperienceState copyWith({ List? experiences, String? selectedExperienceId, bool clearSelection = false, ExperienceEmotion? filterEmotion, bool clearFilter = false, ExperienceAuthor? profile, }) { return ExperienceState( experiences: experiences ?? this.experiences, selectedExperienceId: clearSelection ? null : selectedExperienceId ?? this.selectedExperienceId, filterEmotion: clearFilter ? null : filterEmotion ?? this.filterEmotion, profile: profile ?? this.profile, ); } } class ExperienceController extends Notifier { @override ExperienceState build() { final experiences = _seedExperiences(); return ExperienceState( experiences: experiences, selectedExperienceId: experiences.first.id, filterEmotion: null, profile: const ExperienceAuthor( name: 'Руслан', facets: [ ProfileFacet(name: 'темп', value: 'спокойно, без очередей'), ProfileFacet(name: 'еда', value: 'яркое блюдо важнее кухни'), ProfileFacet( name: 'контекст', value: 'работа днем, прогулки вечером', ), ], ), ); } void selectExperience(String id) { state = state.copyWith(selectedExperienceId: id); } void setEmotionFilter(ExperienceEmotion? emotion) { if (emotion == null) { state = state.copyWith(clearFilter: true); return; } final nextVisible = state.experiences.firstWhere( (item) => item.emotion == emotion, orElse: () => state.experiences.first, ); state = state.copyWith( filterEmotion: emotion, selectedExperienceId: nextVisible.id, ); } void addExperience({ required String placeName, required String dishName, required ExperienceEmotion emotion, required LatLng coordinate, required String context, }) { final experience = PlaceExperience( id: 'local-${DateTime.now().microsecondsSinceEpoch}', placeName: placeName.trim().isEmpty ? 'Новое место' : placeName.trim(), neighborhood: 'рядом', coordinate: coordinate, emotion: emotion, intensity: 3, context: context.trim().isEmpty ? 'личная заметка' : context.trim(), dish: DishSignal( name: dishName.trim().isEmpty ? 'блюдо' : dishName.trim(), reason: 'стоит проверить лично', texture: 'новый сигнал', ), author: state.profile, createdLabel: 'сейчас', ); state = state.copyWith( experiences: [experience, ...state.experiences], selectedExperienceId: experience.id, clearFilter: true, ); } List _seedExperiences() { const author = ExperienceAuthor( name: 'Mira', facets: [ ProfileFacet(name: 'темп', value: 'медленно'), ProfileFacet(name: 'еда', value: 'текстура'), ProfileFacet(name: 'настроение', value: 'тихое внимание'), ], ); return const [ PlaceExperience( id: 'secret-garden', placeName: 'Secret Garden', neighborhood: 'District 1', coordinate: LatLng(10.7752, 106.7009), emotion: ExperienceEmotion.comfort, intensity: 4, context: 'крыша, зелень, хороший разговор', dish: DishSignal( name: 'caramelized pork clay pot', reason: 'мягко собирает вечер', texture: 'густой соус, рис, тепло', ), author: author, createdLabel: 'вчера', ), PlaceExperience( id: 'banh-mi-huynh-hoa', placeName: 'Banh Mi Huynh Hoa', neighborhood: 'District 1', coordinate: LatLng(10.7716, 106.6920), emotion: ExperienceEmotion.energy, intensity: 5, context: 'быстро, плотно, без церемоний', dish: DishSignal( name: 'banh mi dac biet', reason: 'если хочется прямого удара вкуса', texture: 'хруст, паштет, травы', ), author: author, createdLabel: '3 дня назад', ), PlaceExperience( id: 'the-workshop', placeName: 'The Workshop', neighborhood: 'District 1', coordinate: LatLng(10.7740, 106.7042), emotion: ExperienceEmotion.focus, intensity: 4, context: 'ноутбук, кофе, два часа ясности', dish: DishSignal( name: 'egg coffee', reason: 'сладкая пауза между задачами', texture: 'крем, горечь, плотность', ), author: author, createdLabel: 'на неделе', ), PlaceExperience( id: 'oc-dao', placeName: 'Oc Dao', neighborhood: 'District 1', coordinate: LatLng(10.7607, 106.6898), emotion: ExperienceEmotion.curiosity, intensity: 5, context: 'пробовать руками, спорить, заказывать еще', dish: DishSignal( name: 'grilled scallops', reason: 'блюдо ведет сильнее, чем место', texture: 'дым, масло, арахис', ), author: author, createdLabel: 'месяц назад', ), ]; } }