import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../ui/app_shell.dart'; import '../ui/async_state_views.dart'; import '../../features/auth/data/auth_providers.dart'; import '../../core/auth/jwt_decoder.dart'; import '../../features/auth/presentation/login_screen.dart'; import '../../features/profile/presentation/profile_screen.dart'; import '../../features/recipes/presentation/create_recipe_screen.dart'; import '../../features/recipes/presentation/ai_recipe_suggestions_screen.dart'; import '../../features/recipes/presentation/recipe_detail_screen.dart'; import '../../features/recipes/presentation/recipe_edit_screen.dart'; import '../../features/recipes/presentation/recipes_screen.dart'; import '../../features/inventory/presentation/inventory_screen.dart'; import '../../features/inventory/presentation/inventory_detail_screen.dart'; import '../../features/inventory/presentation/create_inventory_screen.dart'; import '../../features/inventory/presentation/inventory_edit_screen.dart'; import '../../features/inventory/presentation/consume_inventory_screen.dart'; import '../../features/inventory/presentation/consumption_history_screen.dart'; import '../../features/meal_plan/presentation/meal_plan_screen.dart'; import '../../features/pantry/presentation/pantry_screen.dart'; import '../../features/import/presentation/import_screen.dart'; import '../../features/admin/presentation/admin_screen.dart'; final appRouterProvider = Provider((ref) { final authState = ref.watch(authStateProvider); return GoRouter( initialLocation: '/', redirect: (context, state) { final isLoading = authState.isLoading; final token = authState.maybeWhen(data: (t) => t, orElse: () => null); final isLoggedIn = token != null && token.isNotEmpty; final location = state.matchedLocation; final isSplash = location == '/'; final isLogin = location == '/login'; if (isLoading) { return isSplash ? null : '/'; } if (isSplash) { return isLoggedIn ? '/recipes' : '/login'; } if (!isLoggedIn && !isLogin) { return '/login'; } if (isLoggedIn && isLogin) { return '/recipes'; } return null; }, routes: [ GoRoute( path: '/', builder: (context, state) => const Scaffold( body: LoadingStateView(label: 'Startar...'), ), ), GoRoute( path: '/login', builder: (context, state) => const LoginScreen(), ), // Detail routes — outside ShellRoute to get full-screen with back button. // /recipes/create must be listed before /recipes/:id to avoid conflict. GoRoute( path: '/recipes/ai-suggestions', builder: (context, state) => const AiRecipeSuggestionsScreen(), ), GoRoute( path: '/recipes/create', builder: (context, state) { final extra = state.extra; String? initialMarkdown; String? initialImageUrl; // Use 'is Map' without type params — Dart reifies generics, so // Map does NOT match Map at runtime. if (extra is Map) { initialMarkdown = extra['markdown'] as String?; initialImageUrl = extra['imageUrl'] as String?; } else if (extra is String) { // Backwards-compat: plain string means markdown only. initialMarkdown = extra; } return CreateRecipeScreen( initialMarkdown: initialMarkdown, initialImageUrl: initialImageUrl, ); }, ), GoRoute( path: '/recipes/:id', redirect: (context, state) { final raw = state.pathParameters['id'] ?? ''; if (int.tryParse(raw) == null) return '/recipes'; return null; }, builder: (context, state) { final id = int.parse(state.pathParameters['id']!); return RecipeDetailScreen(recipeId: id); }, ), GoRoute( path: '/recipes/:id/edit', redirect: (context, state) { final raw = state.pathParameters['id'] ?? ''; if (int.tryParse(raw) == null) return '/recipes'; return null; }, builder: (context, state) { final id = int.parse(state.pathParameters['id']!); return RecipeEditScreen(recipeId: id); }, ), // Inventory detail routes — outside ShellRoute for full-screen. // /inventory/create must be listed before /inventory/:id. GoRoute( path: '/inventory/create', builder: (context, state) { final destination = state.uri.queryParameters['destination']; return CreateInventoryScreen(initialDestination: destination); }, ), GoRoute( path: '/inventory/:id', redirect: (context, state) { final raw = state.pathParameters['id'] ?? ''; if (int.tryParse(raw) == null) return '/inventory'; return null; }, builder: (context, state) { final id = int.parse(state.pathParameters['id']!); return InventoryDetailScreen(itemId: id); }, ), GoRoute( path: '/inventory/:id/edit', redirect: (context, state) { final raw = state.pathParameters['id'] ?? ''; if (int.tryParse(raw) == null) return '/inventory'; return null; }, builder: (context, state) { final id = int.parse(state.pathParameters['id']!); return InventoryEditScreen(itemId: id); }, ), GoRoute( path: '/inventory/:id/consume', redirect: (context, state) { final raw = state.pathParameters['id'] ?? ''; if (int.tryParse(raw) == null) return '/inventory'; return null; }, builder: (context, state) { final id = int.parse(state.pathParameters['id']!); return ConsumeInventoryScreen(itemId: id); }, ), GoRoute( path: '/inventory/:id/history', redirect: (context, state) { final raw = state.pathParameters['id'] ?? ''; if (int.tryParse(raw) == null) return '/inventory'; return null; }, builder: (context, state) { final id = int.parse(state.pathParameters['id']!); return ConsumptionHistoryScreen(itemId: id); }, ), // Shell routes — shared AppShell with navigation bar. ShellRoute( builder: (context, state, child) { return AppShell(location: state.uri.path, child: child); }, routes: [ GoRoute( path: '/recipes', builder: (context, state) => const RecipesScreen(), ), GoRoute( path: '/inventory', builder: (context, state) => const InventoryScreen(), ), GoRoute( path: '/matsedel', builder: (context, state) => const MealPlanScreen(), ), GoRoute( path: '/baslager', builder: (context, state) => const PantryScreen(), ), GoRoute( path: '/import', builder: (context, state) => const ImportScreen(), ), GoRoute( path: '/profile', builder: (context, state) => const ProfileScreen(), ), GoRoute( path: '/admin', redirect: (context, state) { final token = ref.read(authStateProvider).maybeWhen(data: (t) => t, orElse: () => null); return jwtIsAdmin(token) ? null : '/recipes'; }, builder: (context, state) => const AdminScreen(), ), ], ), ], ); });