import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flux/core/services/notification_service.dart';
import 'package:flux/core/utils/version_check_service.dart';
import 'package:flux/features/attachments/data/attachments_repository.dart';
import 'package:flux/features/auth/bloc/auth_cubit.dart';
import 'package:flux/features/company/data/company_repository.dart';
import 'package:flux/features/notes/blocs/notes_cubit.dart';
import 'package:flux/features/notes/data/notes_repository.dart';
import 'package:flux/features/settings/data/settings_repository.dart';
import 'package:flux/features/tasks/data/task_repository.dart';
import 'package:flux/features/tickets/data/tickets_shipping_repository.dart';
import 'package:flux/features/master_data/providers/blocs/provider_list_cubit.dart';
import 'package:flux/features/operations/blocs/operation_list_cubit.dart';
import 'package:flux/features/operations/data/operations_repository.dart';
import 'package:flux/features/settings/blocs/settings_cubit.dart';
import 'package:flux/features/settings/document_sequence/data/document_sequence_repository.dart';
import 'package:flux/features/tickets/blocs/ticket_list_cubit.dart';
import 'package:flux/features/tickets/data/ticket_repository.dart';
import 'package:flux/features/tracking/blocs/tracking_cubit.dart';
import 'package:flux/features/tracking/data/tracking_repository.dart';
import 'package:flux/firebase_options.dart';
import 'package:flux/l10n/app_localizations.dart';
import 'package:get_it/get_it.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/data/core_repository.dart';
import 'package:flux/core/routes/app_router.dart';
import 'package:flux/core/theme/theme.dart';
import 'package:flux/core/theme/bloc/theme_bloc.dart';
import 'package:flux/features/customers/blocs/customers_list_cubit.dart';
import 'package:flux/features/customers/data/customer_repository.dart';
import 'package:flux/features/master_data/products/blocs/product_cubit.dart';
import 'package:flux/features/master_data/products/data/product_repository.dart';
import 'package:flux/features/master_data/providers/data/provider_repository.dart';
import 'package:flux/features/master_data/staff/blocs/staff_cubit.dart';
import 'package:flux/features/master_data/staff/data/staff_repository.dart';
import 'package:flux/features/master_data/store/bloc/store_cubit.dart';
import 'package:flux/features/master_data/store/data/store_repository.dart';
import 'package:flux/features/settings/ui/settings.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:url_launcher/url_launcher.dart';

String? initialRecoveryFragment;
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final initialUri = Uri.base;
  if (initialUri.fragment.contains('access_token=')) {
    initialRecoveryFragment = initialUri.fragment;
  }
  await dotenv.load(fileName: ".env");

  // Inizializza le dipendenze PRIMA di lanciare l'app
  await setupLocator();
  // RIMUOVE IL CARATTERE # DAGLI URL WEB!
  usePathUrlStrategy();
  // Lo Scudo Ninja: Inizializziamo Firebase SOLO sulle piattaforme supportate
  if (kIsWeb || Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
    try {
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      await setupInteractedMessage();
    } catch (e) {
      debugPrint('Errore inizializzazione Firebase: $e');
    }
  }
  runApp(
    MultiBlocProvider(
      providers: [
        BlocProvider<AuthCubit>(create: (context) => AuthCubit()),
        BlocProvider<ThemeBloc>(
          create: (context) => ThemeBloc()..add(LoadThemeEvent()),
        ),
        // Il Vigile Urbano viene inizializzato!
        BlocProvider<SessionCubit>(create: (_) => GetIt.I<SessionCubit>()),

        // Cubit delle feature
        BlocProvider<StoreCubit>(create: (_) => StoreCubit()),
        BlocProvider<CustomersListCubit>(create: (_) => CustomersListCubit()),
        BlocProvider<ProductsCubit>(create: (_) => ProductsCubit()),
        BlocProvider<StaffCubit>(
          create: (_) => StaffCubit()
            ..loadStaffForStore(
              GetIt.I.get<SessionCubit>().state.currentStore!.id!,
            ),
        ),
        BlocProvider<OperationListCubit>(create: (_) => OperationListCubit()),
        BlocProvider<ProviderListCubit>(create: (_) => ProviderListCubit()),
        BlocProvider<SettingsCubit>(create: (_) => SettingsCubit()),
        BlocProvider<TicketListCubit>(create: (_) => TicketListCubit()),
        BlocProvider<OperationListCubit>(create: (_) => OperationListCubit()),
        BlocProvider<TrackingCubit>(create: (_) => TrackingCubit()),
        BlocProvider<NotesCubit>(create: (_) => NotesCubit()),
      ],
      child: const FluxApp(),
    ),
  );
}

Future<void> setupLocator() async {
  final GetIt getIt = GetIt.instance;

  getIt.registerSingleton<SharedPreferences>(
    await SharedPreferences.getInstance(),
  );

  await Supabase.initialize(
    url: dotenv.env['SUPABASE_URL'] ?? '',
    anonKey: dotenv.env['SUPABASE_ANON_KEY'] ?? '',
  );
  //await Supabase.instance.client.auth.signOut();
  getIt.registerSingleton<SupabaseClient>(Supabase.instance.client);

  // Settings
  getIt.registerLazySingleton<AppSettings>(() => AppSettings());

  // Repositories
  getIt.registerLazySingleton<CoreRepository>(
    () => CoreRepository(),
  ); // <-- NUOVO
  getIt.registerLazySingleton<StoreRepository>(() => StoreRepository());
  getIt.registerLazySingleton<CustomerRepository>(() => CustomerRepository());
  getIt.registerLazySingleton<ProductRepository>(() => ProductRepository());
  getIt.registerLazySingleton<StaffRepository>(() => StaffRepository());
  getIt.registerLazySingleton<OperationsRepository>(
    () => OperationsRepository(),
  );
  getIt.registerLazySingleton<ProviderRepository>(() => ProviderRepository());
  getIt.registerLazySingleton<AttachmentsRepository>(
    () => AttachmentsRepository(),
  );
  getIt.registerLazySingleton<TicketRepository>(() => TicketRepository());
  getIt.registerLazySingleton<DocumentSequenceRepository>(
    () => DocumentSequenceRepository(),
  );

  // NOTA: CompanyRepository l'ho tolto perché la logica della Company
  // ora è gestita dal CoreRepository durante l'Onboarding.
  // Se ti serve per altro, rimettilo pure!

  // Inizializziamo il SessionCubit (che prende CoreRepository e SharedPreferences)
  // Usiamo registerSingleton così viene creato subito e inizia ad ascoltare Supabase Auth.
  getIt.registerSingleton<SessionCubit>(
    SessionCubit(getIt<CoreRepository>(), getIt<SharedPreferences>()),
  );
  getIt.registerLazySingleton<CompanyRepository>(() => CompanyRepository());
  getIt.registerLazySingleton<TrackingRepository>(() => TrackingRepository());
  getIt.registerLazySingleton<TicketsShippingRepository>(
    () => TicketsShippingRepository(),
  );
  getIt.registerLazySingleton<NotesRepository>(() => NotesRepository());
  getIt.registerLazySingleton<TasksRepository>(() => TasksRepository());
  getIt.registerLazySingleton<SettingsRepository>(() => SettingsRepository());
}

class FluxApp extends StatefulWidget {
  const FluxApp({super.key});

  @override
  State<FluxApp> createState() => _FluxAppState();
}

class _FluxAppState extends State<FluxApp> {
  late final GoRouter _router;

  @override
  void initState() {
    super.initState();
    // Creiamo il router passandogli il Cubit per i redirect
    _router = AppRouter.createRouter(context.read<SessionCubit>());
    GetIt.I.get<SessionCubit>().setIsMobileDevice(isMobileDevice(context));
  }

  bool isMobileDevice(BuildContext context) {
    if (kIsWeb) {
      return false; // Il web non lo consideriamo "mobile nativo" per i deep link
    }
    return Platform.isAndroid || Platform.isIOS;
  }

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<SessionCubit, SessionState>(
      listenWhen: (previous, current) =>
          previous.status != SessionStatus.authenticated &&
          current.status == SessionStatus.authenticated,
      listener: (context, state) {
        context.read<StoreCubit>().loadStores();
        context.read<StaffCubit>().loadAllStaff();
      },
      builder: (context, sessionState) {
        if (sessionState.status == SessionStatus.initial) {
          return _buildLoadingScreen();
        }

        if (sessionState.status == SessionStatus.error) {
          return _buildSessionErrorScreen(
            state: sessionState,
            context: context,
          );
        }

        return BlocBuilder<ThemeBloc, ThemeState>(
          builder: (context, themeState) {
            return MaterialApp.router(
              title: 'FLUX Gestionale',
              debugShowCheckedModeBanner: false,
              theme: fluxLightTheme,
              darkTheme: fluxDarkTheme,
              themeMode: themeState.currentTheme.themeMode,
              routerConfig: _router,
              localizationsDelegates: AppLocalizations.localizationsDelegates,
              supportedLocales: AppLocalizations.supportedLocales,
              locale: const Locale('it'),

              // 🥷 ECCO LA MAGIA: Avvolgiamo tutta l'app nel nostro checker!
              builder: (context, child) {
                return GlobalUpdateChecker(child: child!);
              },
            );
          },
        );
      },
    );
  }

  Widget _buildLoadingScreen() {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.bolt, size: 64, color: Colors.blue),
              const SizedBox(height: 24),
              const CircularProgressIndicator(),
              const SizedBox(height: 16),
              const Text(
                "Inizializzazione sessione...",
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  color: Colors.grey,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Widget _buildSessionErrorScreen({
  required SessionState state,
  required BuildContext context,
}) {
  return MaterialApp(
    home: Scaffold(
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.wifi_off_rounded, size: 64, color: Colors.grey),
              const SizedBox(height: 16),
              Text(
                state.errorMessage ?? 'Errore nella connessione',
                textAlign: TextAlign.center,
                style: const TextStyle(fontSize: 16),
              ),
              const SizedBox(height: 24),
              ElevatedButton.icon(
                onPressed: () {
                  // Il ninja riprova a lanciare l'inizializzazione
                  context.read<SessionCubit>().initializeSession();
                },
                icon: const Icon(Icons.refresh),
                label: const Text("Riprova a connetterti"),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}

// --- IL WIDGET GUARDIANO DEGLI AGGIORNAMENTI ---
class GlobalUpdateChecker extends StatefulWidget {
  final Widget child;
  const GlobalUpdateChecker({super.key, required this.child});

  @override
  State<GlobalUpdateChecker> createState() => _GlobalUpdateCheckerState();
}

class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
  bool _mustUpdate = false;
  String? _updateUrl;

  @override
  void initState() {
    super.initState();
    _checkVersionAndBlock();
  }

  Future<void> _checkVersionAndBlock() async {
    final updateUrl = await VersionCheckService().checkForceUpdate();

    if (updateUrl != null && mounted) {
      // Invece di aprire un dialog, cambiamo lo stato e attiviamo lo "Scudo"
      setState(() {
        _mustUpdate = true;
        _updateUrl = updateUrl;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    // 1. Se l'app è aggiornata, mostriamo solo l'app normale
    if (!_mustUpdate) return widget.child;

    // 2. Se l'app è vecchia, sovrapponiamo il blocco con uno Stack
    return Stack(
      children: [
        // L'app sotto continua ad esistere, ma è inaccessibile
        widget.child,

        // IL BLOCCO INVALICABILE SOPRA A TUTTO
        Positioned.fill(
          child: Container(
            color: Colors.black.withValues(alpha: 0.85), // Sfondo oscurante
            child: Center(
              // Usiamo Material per ereditare correttamente temi, font e colori
              child: Material(
                color: Colors.transparent,
                child: Container(
                  margin: const EdgeInsets.all(24),
                  padding: const EdgeInsets.all(24),
                  constraints: const BoxConstraints(maxWidth: 400),
                  decoration: BoxDecoration(
                    color: Theme.of(context).scaffoldBackgroundColor,
                    borderRadius: BorderRadius.circular(16),
                    boxShadow: const [
                      BoxShadow(
                        color: Colors.black54,
                        blurRadius: 20,
                        offset: Offset(0, 10),
                      ),
                    ],
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            kIsWeb ? Icons.cached : Icons.system_update,
                            color: Colors.orange,
                            size: 32,
                          ),
                          const SizedBox(width: 12),
                          Flexible(
                            child: Text(
                              kIsWeb
                                  ? "Aggiornamento"
                                  : "Aggiornamento Obbligatorio",
                              style: Theme.of(context).textTheme.titleLarge
                                  ?.copyWith(fontWeight: FontWeight.bold),
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 16),
                      Text(
                        kIsWeb
                            ? "È stata rilasciata una nuova versione dell'applicazione. Ricarica la pagina per continuare."
                            : "Per continuare ad utilizzare l'applicazione è necessario scaricare e installare l'ultimo aggiornamento.",
                        textAlign: TextAlign.center,
                        style: const TextStyle(fontSize: 16),
                      ),
                      const SizedBox(height: 24),
                      if (kIsWeb)
                        FilledButton.icon(
                          icon: const Icon(Icons.refresh),
                          label: const Text("RICARICA ORA"),
                          style: FilledButton.styleFrom(
                            minimumSize: const Size(double.infinity, 50),
                          ),
                          onPressed: () async {
                            // Trick cross-platform per fare il reload
                            await launchUrl(
                              Uri.parse(Uri.base.toString()),
                              webOnlyWindowName: '_self',
                            );
                          },
                        )
                      else
                        FilledButton.icon(
                          icon: const Icon(Icons.download),

                          label: const Text("SCARICA AGGIORNAMENTO"),
                          style: FilledButton.styleFrom(
                            minimumSize: const Size(double.infinity, 50),
                            backgroundColor: Colors.blue,
                          ),
                          onPressed: () async {
                            if (_updateUrl != null) {
                              final url = Uri.parse(_updateUrl!);
                              await launchUrl(
                                url,
                                mode: LaunchMode.externalApplication,
                              );
                            }
                          },
                        ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}
