import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:nm/nm.dart';

import '../../features/benchmark/presentation/benchmark_screen.dart';
import '../../features/benchmark/presentation/map_benchmark_screen.dart';
import '../../features/benchmark/presentation/rogue_shooter_screen.dart';
import '../../features/benchmark/presentation/sprite_benchmark_screen.dart';
import '../../features/benchmark/presentation/video_benchmark_screen.dart';
import '../../features/benchmark/presentation/vsync_benchmark_screen.dart';
import '../../features/home/presentation/home_screen.dart';
import '../../features/material_demo/presentation/material_demo_screen.dart';
import '../../features/matrix_rgb/presentation/matrix_screen.dart';
import '../../features/morse_led/presentation/led_screen.dart';
import '../../features/news_api/presentation/news_screen.dart';
import '../../features/settings/presentation/settings_screen/settings_screen.dart';
import '../../features/settings/presentation/wifi_settings_screen/accesspoint_screen.dart';
import '../../features/settings/presentation/wifi_settings_screen/wifi_settings_screen.dart';
import '../../features/system_resources/presentation/system_resources_screen.dart';
import '../widgets/home_scaffold.dart';
import 'routes.dart';

const ValueKey<String> _scaffoldKey = ValueKey<String>('App scaffold');

final goRouter = GoRouter(
  initialLocation: '/',
  debugLogDiagnostics: false,
  routes: [
    GoRoute(
      path: '/',
      redirect: (_, __) => '/home',
    ),
    GoRoute(
      path: '/home',
      name: RoutesHome.home.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.home,
          child: HomeScreen(),
        ),
      ),
    ),
    GoRoute(
      path: '/material-demo',
      name: RoutesHome.materialDemo.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.materialDemo,
          child: MaterialDemoScreen(),
        ),
      ),
    ),
    GoRoute(
      path: '/news',
      name: RoutesHome.news.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.news,
          child: NewsScreen(),
        ),
      ),
    ),
    GoRoute(
      path: '/matrix',
      name: RoutesHome.matrix.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.matrix,
          child: MatrixScreen(),
        ),
      ),
    ),
    GoRoute(
      path: '/led',
      name: RoutesHome.led.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.led,
          child: LedScreen(),
        ),
      ),
    ),
    GoRoute(
      path: '/system',
      name: RoutesHome.system.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.system,
          child: SystemResourcesScreen(),
        ),
      ),
    ),
    GoRoute(
      path: '/benchmark',
      name: RoutesHome.benchmark.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.benchmark,
          child: BenchmarkScreen(),
        ),
      ),
      routes: [
        GoRoute(
          path: RoutesBenchmark.sprites.name,
          name: RoutesBenchmark.sprites.name,
          builder: (context, state) => const SpriteBenchmarkScreen(),
        ),
        GoRoute(
          path: RoutesBenchmark.rogueShooter.name,
          name: RoutesBenchmark.rogueShooter.name,
          builder: (context, state) => const RogueShooterScreen(),
        ),
        GoRoute(
          path: RoutesBenchmark.shader.name,
          name: RoutesBenchmark.shader.name,
          builder: (context, state) => const VsyncBenchmarkScreen(),
        ),
        GoRoute(
          path: RoutesBenchmark.video.name,
          name: RoutesBenchmark.video.name,
          builder: (context, state) => const VideoBenchmarkScreen(),
        ),
        GoRoute(
          path: RoutesBenchmark.map.name,
          name: RoutesBenchmark.map.name,
          builder: (context, state) => const MapBenchmarkScreen(),
        ),
      ],
    ),
    GoRoute(
      path: '/settings',
      name: RoutesHome.settings.name,
      pageBuilder: (BuildContext context, GoRouterState state) =>
          FadeTransitionPage(
        key: _scaffoldKey,
        child: const HomeScaffold(
          selectedTab: RoutesHome.settings,
          child: SettingsScreen(),
        ),
      ),
      routes: [
        GoRoute(
          path: RoutesSettings.wifi.name,
          name: RoutesSettings.wifi.name,
          builder: (context, state) => const WifiSettingsScreen(),
          routes: [
            GoRoute(
              path: 'accesspoint',
              name: RoutesSettings.accesspoint.name,
              builder: (context, state) {
                if (state.extra == null) {
                  return const AccessPointScreen();
                }
                final accessPoint = state.extra as NetworkManagerAccessPoint;
                return AccessPointScreen(
                  accessPoint: accessPoint,
                );
              },
            ),
          ],
        ),
      ],
    ),
  ],
);

/// A page that fades in and out.
/// From the official Go Router Example:
/// https://github.com/flutter/packages/blob/6701c9e618041574cf4cc53cb028a38de8322b53/packages/go_router/example/lib/books/main.dart#L154
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class FadeTransitionPage extends CustomTransitionPage<void> {
  /// Creates a [FadeTransitionPage].
  FadeTransitionPage({
    required LocalKey super.key,
    required super.child,
  }) : super(
            transitionsBuilder: (BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                    Widget child) =>
                FadeTransition(
                  opacity: animation.drive(_curveTween),
                  child: child,
                ));

  static final CurveTween _curveTween = CurveTween(curve: Curves.easeIn);
}
