import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/api/client.dart'; import '../core/api/endpoints.dart'; import '../core/api/exceptions.dart'; import '../models/idea.dart'; import '../models/collaboration.dart'; class IdeasState { final List ideas; final Idea? selectedIdea; final bool isLoading; final String? error; final String viewMode; IdeasState({ this.ideas = const [], this.selectedIdea, this.isLoading = false, this.error, this.viewMode = 'list', }); IdeasState copyWith({ List? ideas, Idea? selectedIdea, bool? isLoading, String? error, String? viewMode, }) => IdeasState( ideas: ideas ?? this.ideas, selectedIdea: selectedIdea ?? this.selectedIdea, isLoading: isLoading ?? this.isLoading, error: error, viewMode: viewMode ?? this.viewMode, ); } class IdeasNotifier extends StateNotifier { final ApiClient _api; IdeasNotifier(this._api) : super(IdeasState()); Future loadIdeas({String? workspaceId}) async { state = state.copyWith(isLoading: true, error: null); try { final params = {}; if (workspaceId != null) params['workspace_id'] = workspaceId; final response = await _api.get(Endpoints.ideas, params: params); final list = (response.data as List) .map((e) => Idea.fromJson(e as Map)) .toList(); state = state.copyWith(ideas: list, isLoading: false); } on ApiException catch (e) { state = state.copyWith(isLoading: false, error: e.message); } } Future loadIdea(String id) async { state = state.copyWith(isLoading: true, error: null); try { final response = await _api.get(Endpoints.idea(id)); final idea = Idea.fromJson(response.data as Map); state = state.copyWith(selectedIdea: idea, isLoading: false); } on ApiException catch (e) { state = state.copyWith(isLoading: false, error: e.message); } } Future createIdea(CreateIdeaRequest request) async { try { final response = await _api.post(Endpoints.ideas, data: request.toJson()); final idea = Idea.fromJson(response.data as Map); state = state.copyWith( ideas: [idea, ...state.ideas], selectedIdea: idea, ); return true; } on ApiException catch (e) { state = state.copyWith(error: e.message); return false; } } Future updateIdea(String id, UpdateIdeaRequest request) async { try { final response = await _api.patch(Endpoints.idea(id), data: request.toJson()); final updated = Idea.fromJson(response.data as Map); state = state.copyWith( ideas: state.ideas.map((i) => i.id == id ? updated : i).toList(), selectedIdea: updated, ); return true; } on ApiException catch (e) { state = state.copyWith(error: e.message); return false; } } Future deleteIdea(String id) async { try { await _api.delete(Endpoints.idea(id)); state = state.copyWith( ideas: state.ideas.where((i) => i.id != id).toList(), selectedIdea: null, ); return true; } on ApiException catch (e) { state = state.copyWith(error: e.message); return false; } } Future updateFunnel(String ideaId, String status) async { try { final response = await _api.post(Endpoints.ideaFunnel(ideaId), data: { 'status': status, }); final updated = Idea.fromJson(response.data as Map); state = state.copyWith( ideas: state.ideas.map((i) => i.id == ideaId ? updated : i).toList(), selectedIdea: updated, ); return true; } on ApiException catch (e) { state = state.copyWith(error: e.message); return false; } } void setViewMode(String mode) { state = state.copyWith(viewMode: mode); } void clearError() { state = state.copyWith(error: null); } } final ideasProvider = StateNotifierProvider((ref) { final api = ref.read(apiClientProvider); return IdeasNotifier(api); }); class IdeaCommentsState { final List comments; final bool isLoading; final String? error; IdeaCommentsState({ this.comments = const [], this.isLoading = false, this.error, }); IdeaCommentsState copyWith({ List? comments, bool? isLoading, String? error, }) => IdeaCommentsState( comments: comments ?? this.comments, isLoading: isLoading ?? this.isLoading, error: error, ); } class IdeaCommentsNotifier extends StateNotifier { final ApiClient _api; final String ideaId; IdeaCommentsNotifier(this._api, this.ideaId) : super(IdeaCommentsState()); Future loadComments() async { state = state.copyWith(isLoading: true); try { final response = await _api.get(Endpoints.ideaComments(ideaId)); final list = (response.data as List) .map((e) => Comment.fromJson(e as Map)) .toList(); state = state.copyWith(comments: list, isLoading: false); } on ApiException catch (e) { state = state.copyWith(isLoading: false, error: e.message); } } Future addComment(String body, {String? parentId}) async { try { final response = await _api.post(Endpoints.ideaComments(ideaId), data: { 'body': body, if (parentId != null) 'parent_id': parentId, }); final comment = Comment.fromJson(response.data as Map); state = state.copyWith(comments: [...state.comments, comment]); return true; } on ApiException catch (e) { state = state.copyWith(error: e.message); return false; } } Future toggleVote(String ideaId) async { try { await _api.post(Endpoints.ideaVote(ideaId)); } on ApiException catch (e) { state = state.copyWith(error: e.message); } } } final ideaCommentsProvider = StateNotifierProvider.family( (ref, ideaId) { final api = ref.read(apiClientProvider); return IdeaCommentsNotifier(api, ideaId); }); class IdeaActivityState { final List activities; final bool isLoading; IdeaActivityState({ this.activities = const [], this.isLoading = false, }); IdeaActivityState copyWith({ List? activities, bool? isLoading, }) => IdeaActivityState( activities: activities ?? this.activities, isLoading: isLoading ?? this.isLoading, ); } class IdeaActivityNotifier extends StateNotifier { final ApiClient _api; final String ideaId; IdeaActivityNotifier(this._api, this.ideaId) : super(IdeaActivityState()); Future loadActivities() async { state = state.copyWith(isLoading: true); try { final response = await _api.get(Endpoints.ideaActivity(ideaId)); final list = (response.data as List) .map((e) => Activity.fromJson(e as Map)) .toList(); state = state.copyWith(activities: list, isLoading: false); } catch (_) { state = state.copyWith(isLoading: false); } } } final ideaActivityProvider = StateNotifierProvider.family( (ref, ideaId) { final api = ref.read(apiClientProvider); return IdeaActivityNotifier(api, ideaId); });