import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:latlong2/latlong.dart';

import '../../features/mapflow/presentation/admin_voice_experiences_screen.dart';
import '../../features/mapflow/presentation/mapflow_shell.dart';

class MapflowRoutes {
  const MapflowRoutes._();

  static const home = '/';
  static const addExperience = '/experience/new';
  static const adminReviews = '/admin/reviews';

  static String addExperienceLocation({required LatLng? coordinate}) {
    return Uri(
      path: addExperience,
      queryParameters: {
        if (coordinate != null) ...{
          'lat': coordinate.latitude.toString(),
          'lng': coordinate.longitude.toString(),
        },
      },
    ).toString();
  }
}

GoRouter createAppRouter() {
  return GoRouter(
    errorBuilder: (context, state) => const MapflowShell(),
    routes: [
      GoRoute(
        path: MapflowRoutes.home,
        builder: (context, state) => const MapflowShell(),
      ),
      GoRoute(
        path: MapflowRoutes.addExperience,
        pageBuilder: (context, state) {
          final queryParameters = state.uri.queryParameters;
          return CustomTransitionPage<void>(
            fullscreenDialog: true,
            key: state.pageKey,
            child: AddExperienceFlow(
              coordinate: _coordinateFromQuery(queryParameters),
            ),
            transitionsBuilder: (context, animation, _, child) {
              return SlideTransition(
                position: Tween<Offset>(
                  begin: const Offset(0, 1),
                  end: Offset.zero,
                ).animate(animation),
                child: child,
              );
            },
          );
        },
      ),
      GoRoute(
        path: MapflowRoutes.adminReviews,
        builder: (context, state) => const AdminVoiceExperiencesScreen(),
      ),
    ],
  );
}

LatLng? _coordinateFromQuery(Map<String, String> queryParameters) {
  final lat = queryParameters['lat'];
  final lng = queryParameters['lng'];
  if (lat == null && lng == null) {
    return null;
  }
  if (lat == null || lng == null) {
    throw StateError('Both lat and lng query parameters are required.');
  }

  final latitude = double.parse(lat);
  final longitude = double.parse(lng);
  if (!latitude.isFinite || !longitude.isFinite) {
    throw StateError('Review coordinate query parameters must be finite.');
  }

  return LatLng(latitude, longitude);
}
