import 'dart:async';

import 'package:bot_toast/bot_toast.dart';
import 'package:be_happy/core/app_colors.dart';
import 'package:be_happy/di/service_locator.dart';
import 'package:be_happy/domain/entities/user_profile.dart';
import 'package:be_happy/domain/usecase/get_available_subscriptions_usecase.dart';
import 'package:be_happy/domain/usecase/get_certificates_usecase.dart';
import 'package:be_happy/domain/usecase/get_client_subscriptions_usecase.dart';
import 'package:be_happy/domain/usecase/get_profile_usecase.dart';
import 'package:be_happy/domain/usecase/get_scooter_by_title_usecase.dart';
import 'package:be_happy/domain/usecase/get_subscription_by_id_usecase.dart';
import 'package:be_happy/domain/usecase/is_pin_set_usecase.dart';
import 'package:be_happy/domain/usecase/purchase_certificate_usecase.dart';
import 'package:be_happy/presentation/event/payment_confirm_event.dart';
import 'package:be_happy/presentation/event/pin_event.dart';
import 'package:be_happy/presentation/event/subscription_list_event.dart';
import 'package:be_happy/presentation/screens/block_screen.dart';
import 'package:be_happy/presentation/screens/documents_screen.dart';
import 'package:be_happy/presentation/screens/edit_profile_screen.dart';
import 'package:be_happy/presentation/screens/map_screen.dart';
import 'package:be_happy/presentation/screens/news_screen.dart';
import 'package:be_happy/presentation/screens/onboarding_screen.dart';
import 'package:be_happy/presentation/screens/order_history_detail_screen.dart';
import 'package:be_happy/presentation/screens/payment_confirm_screen.dart';
import 'package:be_happy/presentation/screens/profile_screen.dart';
import 'package:be_happy/presentation/screens/promo_code_screen.dart';
import 'package:be_happy/presentation/screens/qr_scan_info_screen.dart';
import 'package:be_happy/presentation/screens/scooter_code_input_screen.dart';
import 'package:be_happy/presentation/screens/scooter_detail_screen.dart';
import 'package:be_happy/presentation/screens/send_photo_screen.dart';
import 'package:be_happy/presentation/screens/subscription_list_screen.dart';
import 'package:be_happy/presentation/screens/support_screen.dart';
import 'package:be_happy/presentation/screens/top_up_screen.dart';
import 'package:be_happy/presentation/viewmodel/splash_bloc.dart';
import 'package:be_happy/presentation/viewmodel/susbcription_details_bloc.dart';
import 'package:be_happy/presentation/viewmodel/top_up_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:geolocator/geolocator.dart';
import 'package:go_router/go_router.dart';
import 'package:path/path.dart';

import '../../domain/entities/scooter.dart';
import '../../domain/usecase/activate_subscription_usecase.dart';
import '../../domain/usecase/book_scooter_usecase.dart';
import '../../domain/usecase/create_pin_usecase.dart';
import '../../domain/usecase/get_address_by_point_usecase.dart';
import '../../domain/usecase/get_available_tariffs_usecase.dart';
import '../../domain/usecase/get_client_orders_usecase.dart';
import '../../domain/usecase/get_map_settings_usecase.dart';
import '../../domain/usecase/get_payment_cards_usecase.dart';
import '../../domain/usecase/get_pedestrian_routes_usecase.dart';
import '../../domain/usecase/get_scooter_order_by_id_usecase.dart';
import '../../domain/usecase/get_scooter_usecase.dart';
import '../../domain/usecase/pay_ride_usecase.dart';
import '../../domain/usecase/remove_payment_card_usecase.dart';
import '../../domain/usecase/save_map_settings_usecase.dart';
import '../../domain/usecase/set_main_payment_card_usecase.dart';
import '../../domain/usecase/verify_pin_usecase.dart';
import '../components/scooter_bottom_sheet.dart';
import '../components/sheet/current_rides_sheet.dart';
import '../components/sheet/map_settings_sheet.dart';
import '../components/sheet/payment_method_sheet.dart';
import '../components/sheet/reserved_ride_sheet.dart';
import '../components/sheet/tariff_sheet.dart';
import '../event/current_rides_event.dart';
import '../event/edit_profile_event.dart';
import '../event/map_settings_modal_event.dart';
import '../event/payment_methods_event.dart';
import '../event/profile_event.dart';
import '../event/scooter_detail_modal_event.dart';
import '../event/subscription_details_event.dart';
import '../event/tariff_sheet_event.dart';
import '../event/top_up_event.dart';
import '../screens/add_card_screen.dart'; // ← новый импорт
import '../screens/license_agreement_screen.dart';
import '../screens/notifications_screen.dart';
import '../screens/order_history_screen.dart';
import '../screens/payment_methods_screen.dart';
import '../screens/phone_login_screen.dart';
import '../screens/phone_screen.dart';
import '../screens/pin_login_screen.dart';
import '../screens/privacy_policy_screen.dart';
import '../screens/qr_scan_screen.dart';
import '../screens/splash_screen.dart';
import '../screens/subscription_details_screen.dart';
import '../state/splash_state.dart';
import '../viewmodel/add_card_bloc.dart';
import '../viewmodel/current_rides_bloc.dart';
import '../viewmodel/edit_profile_bloc.dart';
import '../viewmodel/map_settings_modal_bloc.dart';
import '../viewmodel/payment_confirm_bloc.dart';
import '../viewmodel/payment_method_sheet_bloc.dart';
import '../viewmodel/payment_methods_bloc.dart';
import '../viewmodel/pin_bloc.dart';
import '../viewmodel/profile_bloc.dart';
import '../viewmodel/scooter_code_bloc.dart';
import '../viewmodel/scooter_detail_bloc.dart';
import '../viewmodel/scooter_detail_modal_bloc.dart';
import '../viewmodel/subscription_list_bloc.dart';
import '../viewmodel/tariff_sheet_bloc.dart'; // ← новый импорт

class AppRouter {
  final SplashBloc splashBloc;

  AppRouter(this.splashBloc);

  late final GoRouter router = GoRouter(
    debugLogDiagnostics: true,
    initialLocation: '/splash',

    routes: [
      GoRoute(
        path: '/splash',
        builder: (context, state) => const SplashScreen(),
      ),
      GoRoute(path: '/login', builder: (context, state) => const PhoneScreen()),
      GoRoute(
        path: '/verify',
        builder: (context, state) {
          final phone = state.uri.queryParameters['phone'];
          if (phone != null) {
            return PhoneLoginScreen(phoneNumber: phone, tempToken: '');
          }
          throw Exception("Incorrect phone");
        },
      ),
      GoRoute(
        path: '/block',
        builder: (context, state) => const BlockedScreen(),
      ),
      GoRoute(
          path: '/pin',
          builder: (context, state) =>
              BlocProvider(
                create: (context) =>
                PinBloc(
                  createPinUseCase: getIt<CreatePinUseCase>(),
                  verifyPinUsecase: getIt<VerifyPinUseCase>(),
                  isPinSetUsecase: getIt<IsPinSetUsecase>(),
                )..add(PinScreenStarted()),
                child: const PinLoginScreen(),
              )
      ),
      GoRoute(
        path: '/privacy-policy',
        builder: (context, state) => const PrivacyPolicyScreen(),
      ),
      GoRoute(
        path: '/license-agreement',
        builder: (context, state) => const LicenseAgreementScreen(),
      ),
      GoRoute(
        path: '/home',
        builder: (context, state) => const MapScreen(),
        routes: [
          //Modal Bottom Sheets
          GoRoute(
            path: 'scooter-sheet',
            pageBuilder: (context, state) {
              final data = state.extra as Map<String, dynamic>;

              final scooters = data['scooters'] as List<Scooter>;
              final location = data['currentLocation'] as Position;

              return modalPage(
                state: state,
                child: Material(
                  type: MaterialType.transparency,
                  child: BlocProvider(
                    create: (context) =>
                    ScooterDetailModalBloc(
                      getIt<GetAddressByPointUsecase>(),
                      getIt<GetScooterUsecase>(),
                      getIt<GetPedestrianRoutesUsecase>(),
                    )
                      ..add(
                        ScooterDetailModalStarted(
                          scooters,
                          location.latitude,
                          location.longitude,
                        ),
                      ),
                    child: ScooterBottomSheet(),
                  ),
                ),
              );
            },
          ),
          GoRoute(
            path: 'tarif-sheet',
            pageBuilder: (context, state) {
              final scooter = state.extra as Scooter;

              return modalPage(
                state: state,
                child: Material(
                  type: MaterialType.transparency,
                  child: BlocProvider(
                    create: (context) =>
                        TariffSheetBloc(
                          getIt<GetAvailableTariffsUsecase>(),
                          getIt<GetProfileUseCase>(),
                          getIt<GetPaymentCardsUsecase>(),
                          getIt<BookScooterUsecase>(),
                        ),
                    child: TariffSheet(scooter: scooter),
                  ),
                ),
              );
            },
          ),
          GoRoute(
            path: 'current-rides-sheet',
            pageBuilder: (context, state) {
              return modalPage(
                state: state,
                child: Material(
                  type: MaterialType.transparency,
                  child: BlocProvider(
                    create: (context) =>
                    CurrentRidesBloc(getIt<GetClientOrdersUsecase>())
                      ..add(LoadClientOrders()),
                    child: CurrentRidesSheet(),
                  ),
                ),
              );
            },
          ),
          GoRoute(
            path: 'payment-method-sheet',
            pageBuilder: (context, state) {
              return modalPage(
                state: state,
                child: Material(
                  type: MaterialType.transparency,
                  child: BlocProvider(
                    create: (context) =>
                        PaymentMethodSheetBloc(getIt<GetPaymentCardsUsecase>()),
                    child: PaymentMethodSheet(),
                  ),
                ),
              );
            },
          ),

          GoRoute(
            path: 'map-settings-sheet',
            pageBuilder: (context, state) {
              return modalPage(
                state: state,
                child: Material(
                  type: MaterialType.transparency,
                  child: BlocProvider(
                    create: (context) =>
                    MapSettingsModalBloc(
                      getIt<GetMapSettingsUsecase>(),
                      getIt<SaveMapSettingsUsecase>(),
                    )
                      ..add(MapSettingsModalStarted()),
                    child: MapSettingsSheet(),
                  ),
                ),
              );
            },
          ),
          //Sub screens
          GoRoute(
            path: 'profile',
            builder: (context, state) =>
                BlocProvider(
                  create: (context) =>
                  getIt<ProfileBloc>()
                    ..add(ProfileStarted()),
                  child: ProfileScreen(),
                ),
            routes: [
              GoRoute(
                path: 'edit',
                builder: (context, state) =>
                    BlocProvider(
                      create: (context) =>
                      getIt<EditProfileBloc>()
                        ..add(EditProfileStarted()),
                      child: EditProfileScreen(
                        profile: UserProfile(
                          name: '',
                          birthDate: '',
                          phone: '',
                          balance: 23,
                          email: '',
                        ),
                      ),
                    ),
              ),
            ],
          ),
          GoRoute(
            path: 'scooter/:id',
            builder: (context, state) =>
                BlocProvider(
                  create: (context) => getIt<ScooterDetailBloc>(),
                  child: ScooterDetailScreen(),
                ),
          ),
          GoRoute(
            path: 'order-photos/:orderId',
            builder: (context, state) {
              int orderId = int.parse(state.pathParameters['orderId']!);
              return SendPhotoScreen(orderId: orderId);
            },
          ),
          GoRoute(
            path: 'checkout/:orderId',
            builder: (context, state) {
              int orderId = int.parse(state.pathParameters['orderId']!);
              List<int> photoIds = [];
              if (state.extra != null) {
                photoIds = state.extra as List<int>;
              }

              return BlocProvider(
                create: (context) =>
                PaymentConfirmBloc(
                  getIt<PayRideUsecase>(),
                  getIt<GetScooterOrderByIdUsecase>(),
                  getIt<GetPaymentCardsUsecase>(),
                  getIt<GetProfileUseCase>(),
                )
                  ..add(PaymentConfirmStarted(orderId)),
                child: PaymentConfirmScreen(
                  orderId: orderId,
                  photoIds: photoIds,
                ),
              );
            },
          ),
          GoRoute(
            path: 'support',
            builder: (context, state) => const SupportScreen(),
          ),
          GoRoute(
            path: 'documents',
            builder: (context, state) => const DocumentsScreen(),
          ),
          GoRoute(
            path: 'promo',
            builder: (context, state) => const PromoCodeScreen(),
          ),
          GoRoute(
            path: 'subscriptions',
            builder: (context, state) {
              return BlocProvider(
                create: (context) =>
                SubscriptionListBloc(
                  getAvailableSubscriptionsUsecase:
                  getIt<GetAvailableSubscriptionsUsecase>(),
                  getClientSubscriptionsUsecase:
                  getIt<GetClientSubscriptionsUsecase>(),
                )
                  ..add(LoadSubscriptionsEvent()),
                child: SubscriptionsListScreen(),
              );
            },
            routes: [
              GoRoute(
                path: ':id',
                builder: (context, state) {
                  return BlocProvider(
                    create: (context) =>
                    SubscriptionDetailsBloc(
                      getIt<GetSubscriptionByIdUsecase>(),
                      getIt<ActivateSubscriptionUsecase>(),
                      getIt<GetClientSubscriptionsUsecase>(),
                    )
                      ..add(
                        LoadDetailsEvent(
                          int.parse(state.pathParameters['id']!),
                        ),
                      ),
                    child: SubscriptionDetailsScreen(subscriptionId: 1),
                  );
                },
              ),
            ],
          ),
          GoRoute(
            path: 'rules',
            builder: (context, state) => const OnboardingScreen(),
          ),
          GoRoute(
            path: 'news',
            builder: (context, state) => const NewsScreen(),
          ),
          GoRoute(
            path: 'qr-info',
            builder: (context, state) => const QRScanInfoScreen(),
            routes: [
              GoRoute(
                path: 'qr-scan',
                builder: (context, state) => const QrScanScreen(),
              ),
              GoRoute(
                path: 'qr-input',
                builder: (context, state) => BlocProvider(
                  create: (context) =>
                  ScooterCodeBloc(
                    getScooterByTitleUsecase:  getIt<GetScooterByTitleUsecase>(),
                  ),
                  child: ScooterCodeInputScreen(),
                ),
              ),
            ]
          ),
          GoRoute(
            path: 'payment-methods',
            builder: (context, state) =>
                BlocProvider(
                  create: (context) =>
                  PaymentMethodsBloc(
                    getIt<GetPaymentCardsUsecase>(),
                    getIt<RemovePaymentCardUsecase>(),
                    getIt<SetMainPaymentCardUsecase>(),
                    getIt<GetProfileUseCase>(),
                  )
                    ..add(PaymentMethodsStarted()),
                  child: PaymentMethodsScreen(),
                ),
            routes: [
              GoRoute(
                path: 'add-card',
                builder: (context, state) =>
                    BlocProvider(
                      create: (context) => getIt<AddCardBloc>(),
                      child: const AddCardScreen(),
                    ),
              ),
              GoRoute(
                path: 'top-up',
                builder: (context, state) =>
                    BlocProvider(
                      create: (context) =>
                      TopUpBloc(
                        getCertificatesUsecase: getIt<GetCertificatesUsecase>(),
                        purchaseCertificateUsecase:
                        getIt<PurchaseCertificateUsecase>(),
                        getUserCards: getIt<GetPaymentCardsUsecase>(),
                      )
                        ..add(LoadTopUpData()),
                      child: TopUpScreen(),
                    ),
              ),
            ],
          ),
          GoRoute(
            path: 'order-history',
            builder: (context, state) => const OrderHistoryScreen(),
            routes: []
          ),
          GoRoute(
            path: 'notifications',
            builder: (context, state) => const NotificationsScreen(),
          ),
        ],
      ),
    ],

    observers: [BotToastNavigatorObserver()],

    redirect: (BuildContext context, GoRouterState state) {
      final authState = splashBloc.state;
      final currentLocation = state.uri.toString();

      print("inside redirect");
      print(splashBloc.state);
      print(state.uri.toString());

      if (authState is AuthInitial && currentLocation != '/splash') {
        print("splash");
        return '/splash';
      }

      if (authState is AuthFirstLaunch &&
          currentLocation != '/login' &&
          currentLocation != '/privacy-policy' &&
          currentLocation != '/license-agreement') {
        print("login");
        return '/login';
      }

      if (authState is AuthUnauthenticated &&
          currentLocation != '/login' &&
          currentLocation != '/privacy-policy' &&
          currentLocation != '/license-agreement') {
        print("login2");
        return '/login';
      }

      if (authState is AuthAuthenticated) {
        final isComingFromStart =
            currentLocation == '/splash' ||
                currentLocation == '/login' ||
                currentLocation == '/phone';

        if (isComingFromStart) {
          print("redirecting to pin check");
          return '/pin';
        }
      }

      if (authState is AuthPinVerified) {
        if (currentLocation == '/splash' ||
            currentLocation == '/login' ||
            currentLocation == '/pin') {
          return '/home';
        }
      }

      return null;
    },

    refreshListenable: GoRouterRefreshStream(splashBloc.stream),
  );

  CustomTransitionPage modalPage({
    required GoRouterState state,
    required Widget child,
  }) {
    return CustomTransitionPage(
      key: state.pageKey,
      opaque: false,
      barrierDismissible: true,
      barrierColor: Colors.black54,
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return SlideTransition(
          position: animation.drive(
            Tween(
              begin: const Offset(0, 1),
              end: Offset.zero,
            ).chain(CurveTween(curve: Curves.easeOutCubic)),
          ),
          child: child,
        );
      },
      child: child,
    );
  }
}

class GoRouterRefreshStream extends ChangeNotifier {
  late final StreamSubscription<dynamic> _subscription;

  GoRouterRefreshStream(Stream<dynamic> stream) {
    notifyListeners();
    _subscription = stream.asBroadcastStream().listen((dynamic _) {
      print("Stream updated");
      notifyListeners();
    });
  }

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }
}
