import 'package:dio/dio.dart'; import 'package:fintracker_api/fintracker_api.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/api/api_client.dart'; final netWorthBreakdownProvider = FutureProvider.autoDispose((ref) async { final r = await ref.watch(apiProvider).getNetworthApi().networthBreakdown(); return r.data!; }); /// Daily net worth for the last 365 days. final netWorthSeriesProvider = FutureProvider.autoDispose>((ref) async { final now = DateTime.now(); final r = await ref.watch(apiProvider).getNetworthApi().networthSeries( from: now.subtract(const Duration(days: 365)), to: now, ); return r.data ?? const []; }); /// The current (partial) month's cashflow, or null before any data exists. final cashflowThisMonthProvider = FutureProvider.autoDispose((ref) async { final r = await ref.watch(apiProvider).getCashflowApi().cashflowMonthly(months: 1); final rows = r.data ?? const []; return rows.isEmpty ? null : rows.last; }); /// The last 12 months, for the income-vs-expense bar chart. final cashflowLast12Provider = FutureProvider.autoDispose>((ref) async { final r = await ref.watch(apiProvider).getCashflowApi().cashflowMonthly(months: 12); return r.data ?? const []; }); final runwayProvider = FutureProvider.autoDispose((ref) async { final r = await ref.watch(apiProvider).getCashflowApi().cashflowRunway(); return r.data!; }); /// When the metric tables were last rebuilt; null before the first refresh. final metricsStatusProvider = FutureProvider.autoDispose((ref) async { try { final r = await ref.watch(apiProvider).getMetricsApi().metricsStatus(); return r.data; } on DioException catch (e) { if (e.response?.statusCode == 404) return null; rethrow; } }); final dataQualityProvider = FutureProvider.autoDispose>((ref) async { final r = await ref.watch(apiProvider).getMetricsApi().metricsDataQuality(); return r.data ?? const []; }); /// Every dashboard provider, refreshed together after a manual /// `POST /metrics/refresh` or a pull-to-refresh. void invalidateHomeProviders(WidgetRef ref) { ref.invalidate(netWorthBreakdownProvider); ref.invalidate(netWorthSeriesProvider); ref.invalidate(cashflowThisMonthProvider); ref.invalidate(cashflowLast12Provider); ref.invalidate(runwayProvider); ref.invalidate(metricsStatusProvider); ref.invalidate(dataQualityProvider); ref.invalidate(portfolioSummaryHomeProvider); } /// The investment side of the dashboard: one scope-wide summary, `all` by default. /// Null when the ledger is empty, which is the normal state before a broker sync. final portfolioSummaryHomeProvider = FutureProvider.autoDispose((ref) async { try { final r = await ref.watch(apiProvider).getAnalyticsApi().analyticsSummary(); return r.data; } on DioException catch (e) { if (e.response?.statusCode == 404) return null; rethrow; } });