import 'dart:developer' as developer; import 'package:eatvio_app/core/routing/auth_routes.dart'; import 'package:eatvio_app/core/routing/content_routes.dart'; import 'package:eatvio_app/core/routing/main_navigation_routes.dart'; import 'package:eatvio_app/core/routing/other_routes.dart'; import 'package:eatvio_app/core/routing/route_constants.dart'; import 'package:eatvio_app/core/routing/settings_routes.dart'; import 'package:eatvio_app/features/auth/entities/auth_result_entity.dart'; import 'package:flutter/material.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:go_router/go_router.dart'; /// Главный роутер приложения class AppRouter { static GlobalKey navigatorKey = GlobalKey(); // Домены для deep links static const List _deepLinkHosts = ['eatvio.ru', 'www.eatvio.ru']; static GoRouter appRouter = GoRouter( initialLocation: RouteConstants.updateScreen, navigatorKey: navigatorKey, redirect: _handleRedirect, routes: [ ...AuthRoutes.createRoutes(), ...MainNavigationRoutes.createRoutes(), ...ContentRoutes.createRoutes(), ...SettingsRoutes.createRoutes(), ...OtherRoutes.createRoutes(), ], ); /// Обработка редиректов для deep links /// Возвращает null для обычной навигации, чтобы не мешать внутренним переходам static String? _handleRedirect(BuildContext context, GoRouterState state) { final uri = state.uri; final host = uri.host.toLowerCase(); final segments = uri.pathSegments; // Проверяем, является ли это deep link по домену final isDeepLink = _deepLinkHosts.contains(host); // Если это не deep link, не мешаем обычной навигации if (!isDeepLink) { return null; } // Логирование для отладки developer.log( 'Deep link detected: host=$host, path=${uri.path}, segments=$segments', name: 'AppRouter', ); // Проверка на пустой путь или некорректный формат if (segments.isEmpty) { developer.log('Empty segments in deep link, redirecting to feed', name: 'AppRouter'); FlutterNativeSplash.remove(); return RouteConstants.feedScreen; } // Проверка языка (первый сегмент должен быть ru или en) if (segments[0] != 'ru' && segments[0] != 'en') { developer.log( 'Invalid language segment: ${segments[0]}, redirecting to feed', name: 'AppRouter', ); FlutterNativeSplash.remove(); return RouteConstants.feedScreen; } // Обработка deep links с учетом языка // Формат: /{lang}/{type}/{identifier?} if (segments.length == 4) { // Формат: /{lang}/diary/{...} final type = segments[1]; if (type == 'diary') { developer.log('Deep link: diary, redirecting to diary-screen', name: 'AppRouter'); FlutterNativeSplash.remove(); return RouteConstants.diaryScreen; } developer.log( 'Unknown deep link type for 4 segments: $type, redirecting to feed', name: 'AppRouter', ); FlutterNativeSplash.remove(); return RouteConstants.feedScreen; } else if (segments.length == 3) { // Формат: /{lang}/{type}/{identifier} final type = segments[1]; final contentIdentifier = segments[2]; switch (type) { case 'recipe': developer.log('Deep link: recipe/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return '/about-recipes-screen?slug=$contentIdentifier'; case 'blog_post': developer.log('Deep link: blog_post/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return '/blog-post-screen?id=$contentIdentifier'; case 'plan': developer.log('Deep link: plan/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return '/about-plan-screen?slug=$contentIdentifier'; case 'diet': developer.log('Deep link: diet/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return '/about-diet-screen?slug=$contentIdentifier'; case 'chat': developer.log('Deep link: chat/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return RouteConstants.chatSelectScreen; case 'profile': developer.log('Deep link: profile/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return '/profile-screen?slug=$contentIdentifier'; case 'diary': developer.log('Deep link: diary/$contentIdentifier', name: 'AppRouter'); FlutterNativeSplash.remove(); return RouteConstants.diaryScreen; default: developer.log( 'Unknown deep link type: $type, redirecting to feed', name: 'AppRouter', ); FlutterNativeSplash.remove(); return RouteConstants.feedScreen; } } else if (segments.length == 2) { // Формат: /{lang}/{type} - только для chat final type = segments[1]; if (type == 'chat') { developer.log('Deep link: chat', name: 'AppRouter'); FlutterNativeSplash.remove(); return RouteConstants.chatSelectScreen; } else { developer.log( 'Unknown deep link type for 2 segments: $type, redirecting to feed', name: 'AppRouter', ); FlutterNativeSplash.remove(); return RouteConstants.feedScreen; } } else { // Неизвестный формат deep link developer.log( 'Unknown deep link format: ${segments.length} segments, redirecting to feed', name: 'AppRouter', ); FlutterNativeSplash.remove(); return RouteConstants.feedScreen; } } static void navigateToRegisterViaSocial({required AuthResultEntity authResult, required String provider}) { appRouter.pushNamed('registerViaSocialScreen', extra: {'authResult': authResult, 'provider': provider}); } }