//lib/widgets/home/home_page.dart
import 'dart:async';

import 'package:aves/app_mode.dart';
import 'package:aves/geo/uri.dart';
import 'package:aves/model/app/intent.dart';
import 'package:aves/model/app/permissions.dart';
import 'package:aves/model/app_inventory.dart';
import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/entry/extensions/catalog.dart';
import 'package:aves/model/filters/covered/location.dart';
import 'package:aves/model/filters/covered/stored_album.dart';
import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart';
import 'package:aves/services/analysis_service.dart';
import 'package:aves/services/common/services.dart';
import 'package:aves/services/global_search.dart';
import 'package:aves/services/intent_service.dart';
import 'package:aves/services/widget_service.dart';
import 'package:aves/theme/themes.dart';
import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/basic/scaffold.dart';
import 'package:aves/widgets/common/behaviour/routes.dart';
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/search/page.dart';
import 'package:aves/widgets/common/search/route.dart';
import 'package:aves/widgets/editor/entry_editor_page.dart';
import 'package:aves/widgets/explorer/explorer_page.dart';
import 'package:aves/widgets/filter_grids/albums_page.dart';
import 'package:aves/widgets/filter_grids/tags_page.dart';
import 'package:aves/widgets/home/home_error.dart';
import 'package:aves/widgets/map/map_page.dart';
import 'package:aves/widgets/search/collection_search_delegate.dart';
import 'package:aves/widgets/settings/home_widget_settings_page.dart';
import 'package:aves/widgets/settings/screen_saver_settings_page.dart';
import 'package:aves/widgets/viewer/entry_viewer_page.dart';
import 'package:aves/widgets/viewer/screen_saver_page.dart';
import 'package:aves/widgets/wallpaper_page.dart';
import 'package:aves_model/aves_model.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:latlong2/latlong.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';

// ✅ Remote
import 'package:aves/remote/remote_controller.dart';
import 'package:aves/remote/remote_settings.dart';

class HomePage extends StatefulWidget {
  static const routeName = '/';

  // compatibile con aves_app.dart
  final Map? intentData;

  const HomePage({
    super.key,
    this.intentData,
  });

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  AvesEntry? _viewerEntry;
  int? _widgetId;
  String? _initialRouteName, _initialSearchQuery;
  Set<CollectionFilter>? _initialFilters;
  String? _initialExplorerPath;
  (LatLng, double?)? _initialLocationZoom;
  List<String>? _secureUris;
  (Object, StackTrace)? _setupError;

  static const allowedShortcutRoutes = [
    AlbumListPage.routeName,
    CollectionPage.routeName,
    ExplorerPage.routeName,
    MapPage.routeName,
    SearchPage.routeName,
  ];

  @override
  void initState() {
    super.initState();
    _setup();
    imageCache.maximumSizeBytes = 512 * (1 << 20);
  }

  @override
  Widget build(BuildContext context) => AvesScaffold(
        body: _setupError != null
            ? HomeError(
                error: _setupError!.$1,
                stack: _setupError!.$2,
              )
            : null,
      );

  Map<String, Object?> _safeCastIntentMap(Object? raw) {
    if (raw is Map) {
      final out = <String, Object?>{};
      for (final entry in raw.entries) {
        final k = entry.key;
        if (k is String) out[k] = entry.value as Object?;
      }
      return out;
    }
    return <String, Object?>{};
  }

  Future<void> _setup() async {
    try {
      final stopwatch = Stopwatch()..start();

      if (await windowService.isActivity()) {
        // ✅ Permessi Aves originali
        await Permissions.mediaAccess.request();
      }

      var appMode = AppMode.main;
      var error = false;

      final rawIntentData = widget.intentData ?? await IntentService.getIntentData();
      final intentData = _safeCastIntentMap(rawIntentData);
      final intentAction = intentData[IntentDataKeys.action] as String?;

      _initialFilters = null;
      _initialExplorerPath = null;
      _secureUris = null;

      await availability.onNewIntent();
      await androidFileUtils.init();

      if (!{
            IntentActions.edit,
            IntentActions.screenSaver,
            IntentActions.setWallpaper,
          }.contains(intentAction) &&
          settings.isInstalledAppAccessAllowed) {
        unawaited(appInventory.initAppNames());
      }

      if (intentData.values.nonNulls.isNotEmpty) {
        await reportService.log('Intent data=$intentData');

        var intentUri = intentData[IntentDataKeys.uri] as String?;
        final intentMimeType = intentData[IntentDataKeys.mimeType] as String?;

        switch (intentAction) {
          case IntentActions.view:
            appMode = AppMode.view;
            _secureUris = (intentData[IntentDataKeys.secureUris] as List?)?.cast<String>();
          case IntentActions.viewGeo:
            error = true;
            if (intentUri != null) {
              final locationZoom = parseGeoUri(intentUri);
              if (locationZoom != null) {
                _initialRouteName = MapPage.routeName;
                _initialLocationZoom = locationZoom;
                error = false;
              }
            }
            break;

          case IntentActions.edit:
            appMode = AppMode.edit;
          case IntentActions.setWallpaper:
            appMode = AppMode.setWallpaper;

          case IntentActions.pickItems:
            final multiple = (intentData[IntentDataKeys.allowMultiple] as bool?) ?? false;
            debugPrint('pick mimeType=$intentMimeType multiple=$multiple');
            appMode = multiple ? AppMode.pickMultipleMediaExternal : AppMode.pickSingleMediaExternal;

          case IntentActions.pickCollectionFilters:
            appMode = AppMode.pickCollectionFiltersExternal;

          case IntentActions.screenSaver:
            appMode = AppMode.screenSaver;
            _initialRouteName = ScreenSaverPage.routeName;

          case IntentActions.screenSaverSettings:
            _initialRouteName = ScreenSaverSettingsPage.routeName;

          case IntentActions.search:
            _initialRouteName = SearchPage.routeName;
            _initialSearchQuery = intentData[IntentDataKeys.query] as String?;

          case IntentActions.widgetSettings:
            _initialRouteName = HomeWidgetSettingsPage.routeName;
            _widgetId = (intentData[IntentDataKeys.widgetId] as int?) ?? 0;

          case IntentActions.widgetOpen:
            final widgetId = intentData[IntentDataKeys.widgetId] as int?;
            if (widgetId == null) {
              error = true;
            } else {
              await settings.reload();
              final page = settings.getWidgetOpenPage(widgetId);
              switch (page) {
                case WidgetOpenPage.collection:
                  _initialFilters = settings.getWidgetCollectionFilters(widgetId);
                case WidgetOpenPage.viewer:
                  appMode = AppMode.view;
                  intentUri = settings.getWidgetUri(widgetId);
                case WidgetOpenPage.home:
                case WidgetOpenPage.updateWidget:
                  break;
              }
              unawaited(WidgetService.update(widgetId));
            }

          default:
            final extraRoute = intentData[IntentDataKeys.page] as String?;
            if (allowedShortcutRoutes.contains(extraRoute)) {
              _initialRouteName = extraRoute;
            }
        }

        if (_initialFilters == null) {
          final extraFilters = (intentData[IntentDataKeys.filters] as List?)?.cast<String>();
          _initialFilters = extraFilters?.map(CollectionFilter.fromJson).nonNulls.toSet();
        }
        _initialExplorerPath = intentData[IntentDataKeys.explorerPath] as String?;

        switch (appMode) {
          case AppMode.view:
          case AppMode.edit:
          case AppMode.setWallpaper:
            if (intentUri != null) {
              _viewerEntry = await _initViewerEntry(uri: intentUri, mimeType: intentMimeType);
            }
            error = _viewerEntry == null;
          default:
            break;
        }
      }

      if (error) {
        debugPrint('Failed to init app mode=$appMode for intent data=$intentData. Fallback to main mode.');
        appMode = AppMode.main;
      }

      context.read<ValueNotifier<AppMode>>().value = appMode;
      unawaited(reportService.setCustomKey('app_mode', appMode.toString()));

      // ✅ Remote: seed debug + icona coerente
      unawaited(RemoteSettings.debugSeedIfEmpty());
      unawaited(RemoteController.instance.initBusFromSettings());

      switch (appMode) {
        case AppMode.main:
        case AppMode.pickCollectionFiltersExternal:
        case AppMode.pickSingleMediaExternal:
        case AppMode.pickMultipleMediaExternal:
          unawaited(GlobalSearch.registerCallback());
          unawaited(AnalysisService.registerCallback());

          final source = context.read<CollectionSource>();




          // ✅ Aves originale: init SOLO se non già full scope
          if (source.loadedScope != CollectionSource.fullScope) {
            await reportService.log(
              'Initialize source to start app with mode=$appMode, loaded scope=${source.loadedScope}',
            );
            final loadTopEntriesFirst =
                settings.homeNavItem.route == CollectionPage.routeName &&
                settings.homeCustomCollection.isEmpty;
            source.canAnalyze = true;

            debugPrint('DEBUG home_page: starting source.init (loadTopEntriesFirst=$loadTopEntriesFirst)');


try {
  await source.init(
    scope: CollectionSource.fullScope,
    loadTopEntriesFirst: loadTopEntriesFirst,
  );

  final folders = await localMediaDb.buildFoldersInMemory(source);
  await localMediaDb.saveFoldersBatch(folders.values.toList());

  await source.initFoldersCache();

} catch (e, st) {
  debugPrint('ERROR home_page: source.init failed: $e\n$st');
  rethrow;
}

}


          // ✅ Remote: dopo init locale, ma non blocca
          unawaited(RemoteController.instance.onAppStart(
            source: source,
            resumeBootstrapIfEnabled: true,
          ));

        case AppMode.screenSaver:
          await reportService.log('Initialize source to start screen saver');
          final source = context.read<CollectionSource>();
          source.canAnalyze = false;
          await source.init(scope: settings.screenSaverCollectionFilters);

        case AppMode.view:
          if (_isViewerSourceable(_viewerEntry) && _secureUris == null) {
            final directory = _viewerEntry?.directory;
            if (directory != null) {
              unawaited(AnalysisService.registerCallback());
              await reportService.log('Initialize source to view item in directory $directory');
              final source = context.read<CollectionSource>();
              source.canAnalyze = true;
              await source.init(scope: {StoredAlbumFilter(directory, null)});
            }
          } else {
            await _initViewerEssentials();
          }

        case AppMode.edit:
        case AppMode.setWallpaper:
          await _initViewerEssentials();

        default:
          break;
      }

      debugPrint('Home setup complete in ${stopwatch.elapsed.inMilliseconds}ms');

      unawaited(
        Navigator.maybeOf(context)?.pushAndRemoveUntil(
          await _getRedirectRoute(appMode),
          (route) => false,
        ),
      );
    } catch (error, stack) {
      debugPrint('failed to setup app with error=$error\n$stack');
      setState(() => _setupError = (error, stack));
    }
  }

  Future<void> _initViewerEssentials() async {
    await localMediaDb.init();
  }

  bool _isViewerSourceable(AvesEntry? viewerEntry) {
    return viewerEntry != null &&
        viewerEntry.directory != null &&
        !settings.hiddenFilters.any((filter) => filter.test(viewerEntry));
  }

  Future<AvesEntry?> _initViewerEntry({required String uri, required String? mimeType}) async {
    if (uri.startsWith('/')) {
      uri = Uri.file(uri).toString();
    }
    final entry = await mediaFetchService.getEntry(uri, mimeType);
    if (entry != null) {
      await entry.catalog(background: false, force: false, persist: false);
    }
    return entry;
  }

  Future<Route> _getRedirectRoute(AppMode appMode) async {
    String routeName;
    Set<CollectionFilter?>? filters;

    switch (appMode) {
      case AppMode.setWallpaper:
        return DirectMaterialPageRoute(
          settings: const RouteSettings(name: WallpaperPage.routeName),
          builder: (_) => WallpaperPage(entry: _viewerEntry),
        );

      case AppMode.view:
        AvesEntry viewerEntry = _viewerEntry!;
        CollectionLens? collection;

        final source = context.read<CollectionSource>();
        final album = viewerEntry.directory;
        if (album != null) {
          final loadingCompleter = Completer();
          final stateNotifier = source.stateNotifier;
          void _onSourceStateChanged() {
            if (stateNotifier.value != SourceState.loading) {
              stateNotifier.removeListener(_onSourceStateChanged);
              loadingCompleter.complete();
            }
          }

          stateNotifier.addListener(_onSourceStateChanged);
          _onSourceStateChanged();
          await loadingCompleter.future;

          collection = CollectionLens(
            source: source,
            filters: {StoredAlbumFilter(album, source.getStoredAlbumDisplayName(context, album))},
            listenToSource: false,
            stackBursts: false,
          );

          final viewerEntryPath = viewerEntry.path;
          final collectionEntry =
              collection.sortedEntries.firstWhereOrNull((entry) => entry.path == viewerEntryPath);
          if (collectionEntry != null) {
            viewerEntry = collectionEntry;
          } else {
            collection = null;
          }
        }

        return DirectMaterialPageRoute(
          settings: const RouteSettings(name: EntryViewerPage.routeName),
          builder: (_) => EntryViewerPage(collection: collection, initialEntry: viewerEntry),
        );

      case AppMode.edit:
        return DirectMaterialPageRoute(
          settings: const RouteSettings(name: EntryViewerPage.routeName),
          builder: (_) => ImageEditorPage(entry: _viewerEntry!),
        );

      default:
        routeName = _initialRouteName ?? settings.homeNavItem.route;
        filters = _initialFilters ??
            (settings.homeNavItem.route == CollectionPage.routeName ? settings.homeCustomCollection : {});
    }

    Route buildRoute(WidgetBuilder builder) => DirectMaterialPageRoute(
          settings: RouteSettings(name: routeName),
          builder: builder,
        );

    final source = context.read<CollectionSource>();
    switch (routeName) {
      case AlbumListPage.routeName:
        return buildRoute((context) => const AlbumListPage(initialGroup: null));
      case TagListPage.routeName:
        return buildRoute((context) => const TagListPage(initialGroup: null));
      case MapPage.routeName:
        return buildRoute((context) {
          final mapCollection = CollectionLens(
            source: source,
            filters: {
              LocationFilter.located,
              if (filters != null) ...filters!,
            },
          );
          return MapPage(
            collection: mapCollection,
            initialLocation: _initialLocationZoom?.$1,
            initialZoom: _initialLocationZoom?.$2,
          );
        });
      case ExplorerPage.routeName:
        final path = _initialExplorerPath ?? settings.homeCustomExplorerPath;
        return buildRoute((context) => ExplorerPage(path: path));
      case HomeWidgetSettingsPage.routeName:
        return buildRoute((context) => HomeWidgetSettingsPage(widgetId: _widgetId!));
      case ScreenSaverPage.routeName:
        return buildRoute((context) => ScreenSaverPage(source: source));
      case ScreenSaverSettingsPage.routeName:
        return buildRoute((context) => const ScreenSaverSettingsPage());
      case SearchPage.routeName:
        return SearchPageRoute(
          delegate: CollectionSearchDelegate(
            searchFieldLabel: context.l10n.searchCollectionFieldHint,
            searchFieldStyle: Themes.searchFieldStyle(context),
            source: source,
            canPop: false,
            initialQuery: _initialSearchQuery,
          ),
        );
      case CollectionPage.routeName:
      default:
        return buildRoute((context) => CollectionPage(source: source, filters: filters));
    }
  }
}
