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

import 'providers/character_provider.dart';
import 'providers/chat_provider.dart';
import 'providers/device_provider.dart';
import 'providers/debug_provider.dart';
import 'providers/ble_provider.dart';
import 'providers/model_provider.dart';
import 'providers/player_provider.dart';
import 'providers/wifi_provider.dart';
import 'screens/app_shell.dart';
import 'screens/ble_provision_screen.dart';
import 'screens/characters_screen.dart';
import 'screens/chat_screen.dart';
import 'screens/debug_screen.dart';
import 'screens/home_screen.dart';
import 'screens/models_screen.dart';
import 'screens/network_screen.dart';
import 'screens/playback_screen.dart';
import 'screens/settings_screen.dart';
import 'screens/trigger_screen.dart';
import 'services/device_storage_service.dart';
import 'services/http_api_service.dart';
import 'services/web_socket_service.dart';
import 'theme/app_theme.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final deviceStorageService = DeviceStorageService();
  final lastDevice = await deviceStorageService.getLastDevice();
  final initialDeviceIp = lastDevice?.ip ?? '127.0.0.1';
  final initialDevicePort = lastDevice?.port ?? 5000;

  final httpApiService = HttpApiService(
    baseUrl: 'http://$initialDeviceIp:$initialDevicePort',
  );
  final webSocketService = WebSocketService();

  runApp(
    MultiProvider(
      providers: [
        Provider<HttpApiService>.value(value: httpApiService),
        Provider<WebSocketService>.value(value: webSocketService),
        ChangeNotifierProvider<DebugProvider>(
          create: (_) => DebugProvider(webSocketService: webSocketService),
        ),
        ChangeNotifierProvider<DeviceProvider>(
          create: (context) => DeviceProvider(
            httpApiService: httpApiService,
            webSocketService: webSocketService,
            deviceStorageService: deviceStorageService,
            debugProvider: context.read<DebugProvider>(),
            initialDeviceIp: initialDeviceIp,
            initialDevicePort: initialDevicePort,
            initialDeviceName: lastDevice?.name,
          )..initialize(),
        ),
        ChangeNotifierProvider<BleProvider>(
          create: (context) => BleProvider(
            debugProvider: context.read<DebugProvider>(),
          ),
        ),
        ChangeNotifierProvider<PlayerProvider>(
          create: (context) => PlayerProvider(
            httpApiService: httpApiService,
            webSocketService: webSocketService,
            debugProvider: context.read<DebugProvider>(),
          )..bootstrap(),
        ),
        ChangeNotifierProvider<WifiProvider>(
          create: (context) => WifiProvider(
            httpApiService: httpApiService,
            webSocketService: webSocketService,
            debugProvider: context.read<DebugProvider>(),
          )..bootstrap(),
        ),
        ChangeNotifierProvider<CharacterProvider>(
          create: (context) => CharacterProvider(
            httpApiService: httpApiService,
            debugProvider: context.read<DebugProvider>(),
          ),
        ),
        ChangeNotifierProvider<ChatProvider>(
          create: (context) => ChatProvider(
            httpApiService: httpApiService,
            debugProvider: context.read<DebugProvider>(),
          ),
        ),
        ChangeNotifierProvider<ModelProvider>(
          create: (context) => ModelProvider(
            httpApiService: httpApiService,
            debugProvider: context.read<DebugProvider>(),
          ),
        ),
      ],
      child: const ShowenApp(),
    ),
  );
}

final GoRouter _router = GoRouter(
  initialLocation: '/',
  routes: [
    StatefulShellRoute.indexedStack(
      builder: (context, state, navigationShell) =>
          AppShell(navigationShell: navigationShell),
      branches: [
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/',
              name: 'home',
              builder: (context, state) => const HomeScreen(),
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/characters',
              name: 'characters',
              builder: (context, state) => const CharactersScreen(),
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/chat',
              name: 'chat',
              builder: (context, state) => const ChatScreen(),
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/playback',
              name: 'playback',
              builder: (context, state) => const PlaybackScreen(),
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/network',
              name: 'network',
              builder: (context, state) => const NetworkScreen(),
              routes: [
                GoRoute(
                  path: 'ble-provision',
                  name: 'ble-provision',
                  builder: (context, state) => const BleProvisionScreen(),
                ),
              ],
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/settings',
              name: 'settings',
              builder: (context, state) => const SettingsScreen(),
              routes: [
                GoRoute(
                  path: 'models',
                  name: 'models',
                  builder: (context, state) => const ModelsScreen(),
                ),
                GoRoute(
                  path: 'trigger',
                  name: 'trigger',
                  builder: (context, state) => const TriggerScreen(),
                ),
                GoRoute(
                  path: 'debug',
                  name: 'debug',
                  builder: (context, state) => const DebugScreen(),
                ),
              ],
            ),
          ],
        ),
      ],
    ),
  ],
);

class ShowenApp extends StatelessWidget {
  const ShowenApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'ShowenV2',
      debugShowCheckedModeBanner: false,
      themeMode: ThemeMode.dark,
      darkTheme: AppTheme.dark(),
      theme: AppTheme.dark(),
      routerConfig: _router,
    );
  }
}
