import 'package:go_router/go_router.dart';

import 'globals.dart';
import 'models/interaction_type_enum.dart';
import 'screens/blocks_screen.dart';
import 'screens/circle_add_users_screen.dart';
import 'screens/circle_create_screen.dart';
import 'screens/circle_editor_screen.dart';
import 'screens/circle_management_screen.dart';
import 'screens/contacts_screen.dart';
import 'screens/editor.dart';
import 'screens/filter_editor_screen.dart';
import 'screens/filters_screen.dart';
import 'screens/follow_request_adjudication_screen.dart';
import 'screens/gallery_browsers_screen.dart';
import 'screens/gallery_screen.dart';
import 'screens/home.dart';
import 'screens/image_editor_screen.dart';
import 'screens/interactions_viewer_screen.dart';
import 'screens/logviewer_screen.dart';
import 'screens/message_thread_screen.dart';
import 'screens/message_threads_browser_screen.dart';
import 'screens/messages_new_thread.dart';
import 'screens/notifications_screen.dart';
import 'screens/post_screen.dart';
import 'screens/search_screen.dart';
import 'screens/settings_screen.dart';
import 'screens/sign_in.dart';
import 'screens/splash.dart';
import 'screens/user_posts_screen.dart';
import 'screens/user_profile_screen.dart';
import 'services/auth_service.dart';

class ScreenPaths {
  static String blocks = '/blocks';
  static String filters = '/filters';
  static String thread = '/thread';
  static String connectHandle = '/connect';
  static String contacts = '/contacts';
  static String splash = '/splash';
  static String settings = '/settings';
  static String messages = '/messages';
  static String timelines = '/';
  static String gallery = '/gallery';
  static String notifications = '/notifications';
  static String signin = '/signin';
  static String manageProfiles = '/switchProfiles';
  static String circleManagement = '/circle_management';
  static String signup = '/signup';
  static String userProfile = '/user_profile';
  static String userPosts = '/user_posts';
  static String likes = '/likes';
  static String reshares = '/reshares';
  static String search = '/search';
  static String logViewer = '/logViewer';
}

bool needAuthChangeInitialized = true;
final _authService = getIt<AccountsService>();
final allowedLoggedOut = [
  ScreenPaths.splash,
  ScreenPaths.signin,
  ScreenPaths.signup
];

final appRouter = GoRouter(
    initialLocation: ScreenPaths.timelines,
    debugLogDiagnostics: true,
    refreshListenable: _authService,
    redirect: (context, state) async {
      final loggedIn = _authService.loggedIn;

      if (!loggedIn && _authService.initializing) {
        return ScreenPaths.splash;
      }

      if (!loggedIn && !allowedLoggedOut.contains(state.uri.toString())) {
        return ScreenPaths.signin;
      }

      if (loggedIn && allowedLoggedOut.contains(state.uri.toString())) {
        return ScreenPaths.timelines;
      }

      return null;
    },
    routes: [
      GoRoute(
        path: ScreenPaths.blocks,
        name: ScreenPaths.blocks,
        builder: (context, state) => const BlocksScreen(),
      ),
      GoRoute(
        path: ScreenPaths.filters,
        name: ScreenPaths.filters,
        builder: (context, state) => const FiltersScreen(),
        routes: [
          GoRoute(
            path: 'new',
            pageBuilder: (context, state) => const NoTransitionPage(
              child: FilterEditorScreen(id: ''),
            ),
          ),
          GoRoute(
            path: 'edit/:id',
            pageBuilder: (context, state) => NoTransitionPage(
                child: FilterEditorScreen(id: state.pathParameters['id']!)),
          )
        ],
      ),
      GoRoute(
        path: ScreenPaths.signin,
        name: ScreenPaths.signin,
        builder: (context, state) => const SignInScreen(),
      ),
      GoRoute(
        path: ScreenPaths.manageProfiles,
        name: ScreenPaths.manageProfiles,
        builder: (context, state) => const SignInScreen(),
      ),
      GoRoute(
        path: ScreenPaths.contacts,
        name: ScreenPaths.contacts,
        pageBuilder: (context, state) => NoTransitionPage(
          name: ScreenPaths.contacts,
          child: const ContactsScreen(),
        ),
      ),
      GoRoute(
        path: '/connect/:id',
        name: ScreenPaths.connectHandle,
        builder: (context, state) => FollowRequestAdjudicationScreen(
            userId: state.pathParameters['id']!),
      ),
      GoRoute(
        path: ScreenPaths.timelines,
        name: ScreenPaths.timelines,
        pageBuilder: (context, state) => NoTransitionPage(
          name: ScreenPaths.timelines,
          child: const HomeScreen(),
        ),
      ),
      GoRoute(
        path: ScreenPaths.messages,
        name: ScreenPaths.messages,
        pageBuilder: (context, state) => const NoTransitionPage(
          child: MessagesScreen(),
        ),
        routes: [
          GoRoute(
            path: 'new_thread',
            pageBuilder: (context, state) => NoTransitionPage(
              child: MessagesNewThread(),
            ),
          ),
        ],
      ),
      GoRoute(
        name: ScreenPaths.thread,
        path: ScreenPaths.thread,
        builder: (context, state) => MessageThreadScreen(
            parentThreadId: state.uri.queryParameters['uri']!),
      ),
      GoRoute(
        name: ScreenPaths.circleManagement,
        path: ScreenPaths.circleManagement,
        builder: (context, state) => const CircleManagementScreen(),
        routes: [
          GoRoute(
            path: 'show/:id',
            builder: (context, state) => CircleEditorScreen(
              circleId: state.pathParameters['id']!,
            ),
          ),
          GoRoute(
            path: 'new',
            builder: (context, state) => const CircleCreateScreen(),
          ),
          GoRoute(
            path: 'add_users/:id',
            builder: (context, state) =>
                CircleAddUsersScreen(circleId: state.pathParameters['id']!),
          ),
        ],
      ),
      GoRoute(
        path: ScreenPaths.settings,
        name: ScreenPaths.settings,
        pageBuilder: (context, state) => const NoTransitionPage(
          child: SettingsScreen(),
        ),
      ),
      GoRoute(
        path: ScreenPaths.gallery,
        name: ScreenPaths.gallery,
        pageBuilder: (context, state) => const NoTransitionPage(
          child: GalleryBrowsersScreen(),
        ),
        routes: [
          GoRoute(
            path: 'show',
            builder: (context, state) => GalleryScreen(
              galleryName: state.extra!.toString(),
            ),
          ),
          GoRoute(
            path: 'edit/:name/image/:id',
            builder: (context, state) => ImageEditorScreen(
              galleryName: state.pathParameters['name']!,
              imageId: state.pathParameters['id']!,
            ),
          ),
        ],
      ),
      GoRoute(
        path: ScreenPaths.notifications,
        name: ScreenPaths.notifications,
        pageBuilder: (context, state) => const NoTransitionPage(
          child: NotificationsScreen(),
        ),
      ),
      GoRoute(
        path: ScreenPaths.splash,
        name: ScreenPaths.splash,
        builder: (context, state) => const SplashScreen(),
      ),
      GoRoute(
          path: '/post',
          redirect: (context, state) {
            if (state.uri.toString() == '/post') {
              return '/post/new';
            }

            return null;
          },
          routes: [
            GoRoute(
              path: 'new',
              builder: (context, state) => const EditorScreen(
                forEditing: false,
              ),
            ),
            GoRoute(
              path: 'edit/:id',
              builder: (context, state) => EditorScreen(
                id: state.pathParameters['id'] ?? 'Not Found',
                forEditing: true,
              ),
            ),
            GoRoute(
              path: 'view/:id/:goto_id',
              builder: (context, state) => PostScreen(
                id: state.pathParameters['id'] ?? 'Not Found',
                goToId: state.pathParameters['goto_id'] ?? 'Not Found',
              ),
            ),
          ]),
      GoRoute(
          path: '/comment',
          redirect: (context, state) {
            if (state.uri.toString() == '/comment') {
              return '/comment/new';
            }

            return null;
          },
          routes: [
            GoRoute(
              path: 'new',
              builder: (context, state) => EditorScreen(
                parentId: state.uri.queryParameters['parent_id'] ?? '',
                forEditing: false,
              ),
            ),
            GoRoute(
              path: 'edit/:id',
              builder: (context, state) => EditorScreen(
                id: state.pathParameters['id'] ?? 'Not Found',
                forEditing: true,
              ),
            ),
          ]),
      GoRoute(
        path: '/user_posts/:id',
        name: ScreenPaths.userPosts,
        builder: (context, state) =>
            UserPostsScreen(userId: state.pathParameters['id']!),
      ),
      GoRoute(
        path: '/likes/:id',
        name: ScreenPaths.likes,
        builder: (context, state) => InteractionsViewerScreen(
          statusId: state.pathParameters['id']!,
          type: InteractionType.like,
        ),
      ),
      GoRoute(
        path: '/reshares/:id',
        name: ScreenPaths.reshares,
        builder: (context, state) => InteractionsViewerScreen(
          statusId: state.pathParameters['id']!,
          type: InteractionType.reshare,
        ),
      ),
      GoRoute(
        path: '/user_profile/:id',
        name: ScreenPaths.userProfile,
        builder: (context, state) =>
            UserProfileScreen(userId: state.pathParameters['id']!),
      ),
      GoRoute(
        path: ScreenPaths.search,
        name: ScreenPaths.search,
        pageBuilder: (context, state) => NoTransitionPage(
          name: ScreenPaths.search,
          child: const SearchScreen(),
        ),
      ),
      GoRoute(
        path: ScreenPaths.logViewer,
        name: ScreenPaths.logViewer,
        pageBuilder: (context, state) => const NoTransitionPage(
          child: LogViewerScreen(),
        ),
      ),
    ]);
