import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart';
import 'package:island/models/activity.dart';
import 'package:island/models/publisher.dart';
import 'package:island/models/realm.dart';
import 'package:island/models/webfeed.dart';
import 'package:island/pods/event_calendar.dart';
import 'package:island/pods/timeline.dart';
import 'package:island/pods/userinfo.dart';
import 'package:island/screens/auth/login_modal.dart';
import 'package:island/screens/notification.dart';
import 'package:island/services/responsive.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/models/post.dart';
import 'package:island/widgets/extended_refresh_indicator.dart';
import 'package:island/widgets/paging/pagination_list.dart';
import 'package:island/widgets/post/compose_sheet.dart';
import 'package:island/widgets/post/post_item.dart';
import 'package:island/widgets/post/post_item_skeleton.dart';
import 'package:island/widgets/post/post_list.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:island/widgets/realm/realm_card.dart';
import 'package:island/widgets/publisher/publisher_card.dart';
import 'package:island/widgets/web_article_card.dart';
import 'package:island/services/event_bus.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
import 'package:island/widgets/post/filters/post_subscription_filter.dart';
import 'package:island/pods/post/post_list.dart';

class ExploreScreen extends HookConsumerWidget {
  const ExploreScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final currentFilter = useState<String?>(null);
    final selectedPublisherNames = useState<List<String>>([]);
    final selectedCategoryIds = useState<List<String>>([]);
    final selectedTagIds = useState<List<String>>([]);
    final notifier = ref.watch(activityListProvider.notifier);

    void handleFilterChange(String? filter) {
      currentFilter.value = filter;
      notifier.applyFilter(filter);
    }

    // Listen for post creation events to refresh activities
    useEffect(() {
      final subscription = eventBus.on<PostCreatedEvent>().listen((event) {
        ref.read(activityListProvider.notifier).refresh();
      });
      return subscription.cancel;
    }, []);

    final now = DateTime.now();

    final query = useState(
      EventCalendarQuery(uname: 'me', year: now.year, month: now.month),
    );

    final events = ref.watch(eventCalendarProvider(query.value));

    final selectedDay = useState(now);

    final user = ref.watch(userInfoProvider);

    final notificationCount = ref.watch(notificationUnreadCountProvider);

    final isWide = isWideScreen(context);

    final hasSubscriptionsSelected = selectedPublisherNames.value.isNotEmpty;

    final filterBar = Card(
      margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
      child: Row(
        children: [
          Row(
            spacing: 8,
            children: [
              IconButton(
                onPressed: hasSubscriptionsSelected
                    ? null
                    : () => handleFilterChange(null),
                icon: Icon(
                  Symbols.explore,
                  fill: currentFilter.value == null ? 1 : null,
                ),
                tooltip: 'explore'.tr(),
                isSelected: currentFilter.value == null,
                color: currentFilter.value == null
                    ? Theme.of(context).colorScheme.primary
                    : null,
              ),
              IconButton(
                onPressed: hasSubscriptionsSelected
                    ? null
                    : () => handleFilterChange('subscriptions'),
                icon: Icon(
                  Symbols.subscriptions,
                  fill: currentFilter.value == 'subscriptions' ? 1 : null,
                ),
                tooltip: 'exploreFilterSubscriptions'.tr(),
                isSelected: currentFilter.value == 'subscriptions',
                color: currentFilter.value == 'subscriptions'
                    ? Theme.of(context).colorScheme.primary
                    : null,
              ),
              IconButton(
                onPressed: hasSubscriptionsSelected
                    ? null
                    : () => handleFilterChange('friends'),
                icon: Icon(
                  Symbols.people,
                  fill: currentFilter.value == 'friends' ? 1 : null,
                ),
                tooltip: 'exploreFilterFriends'.tr(),
                isSelected: currentFilter.value == 'friends',
                color: currentFilter.value == 'friends'
                    ? Theme.of(context).colorScheme.primary
                    : null,
              ),
            ],
          ),
          const Spacer(),
          IconButton(
            onPressed: () {
              context.pushNamed('articles');
            },
            icon: Icon(Symbols.auto_stories),
            tooltip: 'webArticlesStand'.tr(),
          ),
          PopupMenuButton(
            itemBuilder: (context) => [
              PopupMenuItem(
                child: Row(
                  children: [
                    const Icon(Symbols.search),
                    const Gap(12),
                    Text('search').tr(),
                  ],
                ),
                onTap: () {
                  context.pushNamed('universalSearch');
                },
              ),
              PopupMenuItem(
                child: Row(
                  children: [
                    const Icon(Symbols.category),
                    const Gap(12),
                    Text('categoriesAndTags').tr(),
                  ],
                ),
                onTap: () {
                  context.pushNamed('postCategories');
                },
              ),
              PopupMenuItem(
                child: Row(
                  children: [
                    const Icon(Symbols.shuffle),
                    const Gap(12),
                    Text('postShuffle').tr(),
                  ],
                ),
                onTap: () {
                  context.pushNamed('postShuffle');
                },
              ),
            ],
            icon: Icon(Symbols.action_key),
            tooltip: 'search'.tr(),
          ),
        ],
      ).padding(horizontal: 8, vertical: 4),
    );

    final userInfo = ref.watch(userInfoProvider);

    final appBar = isWide
        ? null
        : _buildAppBar(
            currentFilter.value,
            handleFilterChange,
            context,
            hasSubscriptionsSelected,
          );

    return AppScaffold(
      isNoBackground: false,
      appBar: appBar,
      floatingActionButton: userInfo.value != null
          ? FloatingActionButton(
              child: const Icon(Symbols.create),
              onPressed: () {
                showModalBottomSheet(
                  context: context,
                  isScrollControlled: true,
                  useRootNavigator: true,
                  builder: (context) => Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Gap(40),
                      ListTile(
                        contentPadding: const EdgeInsets.symmetric(
                          horizontal: 24,
                        ),
                        leading: const Icon(Symbols.post_add_rounded),
                        title: Text('postCompose').tr(),
                        onTap: () async {
                          Navigator.of(context).pop();
                          await PostComposeSheet.show(context);
                        },
                      ),
                      ListTile(
                        contentPadding: const EdgeInsets.symmetric(
                          horizontal: 24,
                        ),
                        leading: const Icon(Symbols.article),
                        title: Text('articleCompose').tr(),
                        onTap: () async {
                          Navigator.of(context).pop();
                          GoRouter.of(context).pushNamed('articleCompose');
                        },
                      ),
                      const Gap(16),
                    ],
                  ),
                );
              },
            ).padding(bottom: MediaQuery.of(context).padding.bottom)
          : null,
      body: isWide
          ? _buildWideBody(
              context,
              ref,
              filterBar,
              user,
              notificationCount,
              query,
              events,
              selectedDay,
              currentFilter.value,
              selectedPublisherNames,
              selectedCategoryIds,
              selectedTagIds,
            )
          : _buildNarrowBody(context, ref, currentFilter.value),
    );
  }

  Widget _buildActivityList(BuildContext context, WidgetRef ref) {
    final isWide = isWideScreen(context);

    return PaginationWidget(
      provider: activityListProvider,
      notifier: activityListProvider.notifier,
      // Sliver list cannot provide refresh handled by the pagination list
      isRefreshable: false,
      isSliver: true,
      footerSkeletonChild: const PostItemSkeleton(maxWidth: double.infinity),
      contentBuilder: (data, footer) =>
          _ActivityListView(data: data, isWide: isWide, footer: footer),
    );
  }

  Widget _buildPostList(
    BuildContext context,
    WidgetRef ref,
    List<String> selectedPublishers,
    List<String> selectedCategories,
    List<String> selectedTags,
  ) {
    return SliverPostList(
      queryKey: 'explore_filtered',
      query: PostListQuery(
        publishers: selectedPublishers,
        categories: selectedCategories,
        tags: selectedTags,
      ),
      padding: EdgeInsets.zero,
      itemPadding: const EdgeInsets.only(bottom: 8),
    );
  }

  Widget _buildWideBody(
    BuildContext context,
    WidgetRef ref,
    Widget filterBar,
    AsyncValue<SnAccount?> user,
    AsyncValue<int?> notificationCount,
    ValueNotifier<EventCalendarQuery> query,
    AsyncValue<List<dynamic>> events,
    ValueNotifier<DateTime> selectedDay,
    String? currentFilter,
    ValueNotifier<List<String>> selectedPublishers,
    ValueNotifier<List<String>> selectedCategories,
    ValueNotifier<List<String>> selectedTags,
  ) {
    // Use post list when subscription filter is active and publishers are selected
    final usePostList =
        selectedPublishers.value.isNotEmpty ||
        selectedCategories.value.isNotEmpty ||
        selectedTags.value.isNotEmpty;
    final bodyView = usePostList
        ? _buildPostList(
            context,
            ref,
            selectedPublishers.value,
            selectedCategories.value,
            selectedTags.value,
          )
        : _buildActivityList(context, ref);

    final notifier = usePostList
        ? null // Post list handles its own refreshing
        : ref.watch(activityListProvider.notifier);

    final activityState = ref.watch(activityListProvider);

    return Row(
      spacing: 12,
      children: [
        Flexible(
          flex: 3,
          child: ExtendedRefreshIndicator(
            onRefresh: () async {
              await notifier?.refresh();
            },
            child: CustomScrollView(
              slivers: [
                const SliverGap(12),
                if (activityState.value?.isLoading ?? false)
                  SliverToBoxAdapter(
                    child: LinearProgressIndicator().padding(bottom: 8),
                  ),
                SliverToBoxAdapter(child: filterBar),
                const SliverGap(8),
                bodyView,
              ],
            ),
          ),
        ),
        if (user.value != null)
          Flexible(
            flex: 2,
            child: Align(
              alignment: Alignment.topCenter,
              child: SingleChildScrollView(
                child: Column(
                  spacing: 8,
                  children: [
                    Gap(4 + MediaQuery.paddingOf(context).top),
                    PostSubscriptionFilterWidget(
                      initialSelectedPublishers: selectedPublishers.value,
                      initialSelectedCategories: selectedCategories.value,
                      initialSelectedTags: selectedTags.value,
                      onSelectedPublishersChanged: (names) {
                        selectedPublishers.value = names;
                      },
                      onSelectedCategoriesChanged: (ids) {
                        selectedCategories.value = ids;
                      },
                      onSelectedTagsChanged: (ids) {
                        selectedTags.value = ids;
                      },
                    ),
                  ],
                ),
              ),
            ),
          )
        else
          Flexible(
            flex: 2,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Icon(Symbols.emoji_people_rounded, size: 40),
                const Gap(8),
                Text(
                  'Welcome to\nthe Solar Network',
                  style: Theme.of(context).textTheme.titleLarge,
                  textAlign: TextAlign.center,
                ).bold(),
                const Gap(2),
                Text(
                  'Login to explore more!',
                  style: Theme.of(context).textTheme.bodyLarge,
                  textAlign: TextAlign.center,
                ),
                const Gap(4),
                TextButton.icon(
                  onPressed: () {
                    showModalBottomSheet(
                      context: context,
                      useRootNavigator: true,
                      isScrollControlled: true,
                      builder: (context) => LoginModal(),
                    );
                  },
                  icon: const Icon(Symbols.login),
                  label: Text('login').tr(),
                ),
              ],
            ).padding(horizontal: 36, vertical: 16).center(),
          ),
      ],
    ).padding(horizontal: 12);
  }

  PreferredSizeWidget _buildAppBar(
    String? currentFilter,
    void Function(String?) handleFilterChange,
    BuildContext context,
    bool hasSubscriptionsSelected,
  ) {
    final foregroundColor = Theme.of(context).appBarTheme.foregroundColor;

    return AppBar(
      flexibleSpace: Container(
        height: 48,
        margin: EdgeInsets.only(
          left: 8,
          right: 8,
          top: 4 + MediaQuery.of(context).padding.top,
          bottom: 4,
        ),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8),
          child: Row(
            spacing: 8,
            children: [
              IconButton(
                onPressed: hasSubscriptionsSelected
                    ? null
                    : () => handleFilterChange(null),
                icon: Icon(
                  Symbols.explore,
                  color: foregroundColor,
                  fill: currentFilter == null ? 1 : null,
                ),
                tooltip: 'explore'.tr(),
                isSelected: currentFilter == null,
                color: currentFilter == null ? foregroundColor : null,
              ),
              IconButton(
                onPressed: hasSubscriptionsSelected
                    ? null
                    : () => handleFilterChange('subscriptions'),
                icon: Icon(
                  Symbols.subscriptions,
                  color: foregroundColor,
                  fill: currentFilter == 'subscription' ? 1 : null,
                ),
                tooltip: 'exploreFilterSubscriptions'.tr(),
                isSelected: currentFilter == 'subscriptions',
              ),
              IconButton(
                onPressed: hasSubscriptionsSelected
                    ? null
                    : () => handleFilterChange('friends'),
                icon: Icon(
                  Symbols.people,
                  color: foregroundColor,
                  fill: currentFilter == 'friends' ? 1 : null,
                ),
                tooltip: 'exploreFilterFriends'.tr(),
                isSelected: currentFilter == 'friends',
              ),
              const Spacer(),
              IconButton(
                onPressed: () {
                  context.pushNamed('articles');
                },
                icon: Icon(Symbols.auto_stories, color: foregroundColor),
                tooltip: 'webArticlesStand'.tr(),
              ),
              PopupMenuButton(
                itemBuilder: (context) => [
                  PopupMenuItem(
                    child: Row(
                      children: [
                        const Icon(Symbols.search),
                        const Gap(12),
                        Text('search').tr(),
                      ],
                    ),
                    onTap: () {
                      context.pushNamed('universalSearch');
                    },
                  ),
                  PopupMenuItem(
                    child: Row(
                      children: [
                        const Icon(Symbols.category),
                        const Gap(12),
                        Text('categoriesAndTags').tr(),
                      ],
                    ),
                    onTap: () {
                      context.pushNamed('postCategories');
                    },
                  ),
                  PopupMenuItem(
                    child: Row(
                      children: [
                        const Icon(Symbols.shuffle),
                        const Gap(12),
                        Text('postShuffle').tr(),
                      ],
                    ),
                    onTap: () {
                      context.pushNamed('postShuffle');
                    },
                  ),
                ],
                icon: Icon(Symbols.action_key, color: foregroundColor),
                tooltip: 'search'.tr(),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildNarrowBody(
    BuildContext context,
    WidgetRef ref,
    String? currentFilter,
  ) {
    final bodyView = _buildActivityList(context, ref);

    final notifier = ref.watch(activityListProvider.notifier);

    return Expanded(
      child: ClipRRect(
        borderRadius: const BorderRadius.all(Radius.circular(8)),
        child: ExtendedRefreshIndicator(
          onRefresh: notifier.refresh,
          child: CustomScrollView(slivers: [SliverGap(8), bodyView]),
        ),
      ).padding(horizontal: 8),
    );
  }
}

class _DiscoveryActivityItem extends StatelessWidget {
  final Map<String, dynamic> data;

  const _DiscoveryActivityItem({required this.data});

  @override
  Widget build(BuildContext context) {
    final items = data['items'] as List;
    final type = items.firstOrNull?['type'] ?? 'unknown';

    var flexWeights = isWideScreen(context) ? <int>[3, 2, 1] : <int>[4, 1];
    if (type == 'post') flexWeights = <int>[3, 2];

    final height = type == 'post' ? 280.0 : 180.0;

    final contentWidget = switch (type) {
      'post' => SuperListView.separated(
        scrollDirection: Axis.horizontal,
        itemCount: items.length,
        separatorBuilder: (context, index) => const Gap(12),
        padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
        itemBuilder: (context, index) {
          final item = items[index];
          return Container(
            width: 320,
            decoration: BoxDecoration(
              border: Border.all(
                width: 1 / MediaQuery.of(context).devicePixelRatio,
                color: Theme.of(context).dividerColor.withOpacity(0.5),
              ),
              borderRadius: const BorderRadius.all(Radius.circular(8)),
            ),
            child: ClipRRect(
              borderRadius: const BorderRadius.all(Radius.circular(8)),
              child: SingleChildScrollView(
                child: PostActionableItem(
                  item: SnPost.fromJson(item['data']),
                  isCompact: true,
                ),
              ),
            ),
          );
        },
      ),
      _ => CarouselView.weighted(
        flexWeights: flexWeights,
        consumeMaxWeight: false,
        enableSplash: false,
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(8)),
        ),
        itemSnapping: false,
        children: [
          for (final item in items)
            switch (type) {
              'realm' => RealmDiscoveryCard(
                realm: SnRealm.fromJson(item['data']),
                maxWidth: 280,
              ),
              'publisher' => PublisherDiscoveryCard(
                publisher: SnPublisher.fromJson(item['data']),
                maxWidth: 280,
              ),
              'article' => WebArticleDiscoveryCard(
                article: SnWebArticle.fromJson(item['data']),
                maxWidth: 280,
              ),
              _ => const Placeholder(),
            },
        ],
      ),
    };

    return Card(
      margin: EdgeInsets.zero,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Icon(switch (type) {
                'realm' => Symbols.public,
                'publisher' => Symbols.account_circle,
                'article' => Symbols.auto_stories,
                'post' => Symbols.shuffle,
                _ => Symbols.explore,
              }, size: 19),
              const Gap(8),
              Text(
                (switch (type) {
                  'realm' => 'discoverRealms',
                  'publisher' => 'discoverPublishers',
                  'article' => 'discoverWebArticles',
                  'post' => 'discoverShuffledPost',
                  _ => 'unknown',
                }).tr(),
                style: Theme.of(context).textTheme.titleMedium,
              ).padding(top: 1),
            ],
          ).padding(horizontal: 20, top: 8, bottom: 4),
          SizedBox(
            height: height,
            child: contentWidget,
          ).padding(bottom: 8, horizontal: 8),
        ],
      ),
    );
  }
}

class _ActivityListView extends HookConsumerWidget {
  final List<SnTimelineEvent> data;
  final bool isWide;
  final Widget footer;

  const _ActivityListView({
    required this.data,
    required this.isWide,
    required this.footer,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final notifier = ref.watch(activityListProvider.notifier);

    return SliverList.separated(
      itemCount: data.length + 1,
      separatorBuilder: (_, _) => const Gap(8),
      itemBuilder: (context, index) {
        if (index == data.length) {
          return footer;
        }

        final item = data[index];
        if (item.data == null) {
          return const SizedBox.shrink();
        }
        Widget itemWidget;

        switch (item.type) {
          case 'posts.new':
          case 'posts.new.replies':
            itemWidget = PostActionableItem(
              borderRadius: 8,
              item: SnPost.fromJson(item.data!),
              onRefresh: () {
                notifier.refresh();
              },
              onUpdate: (post) {
                notifier.updateOne(index, item.copyWith(data: post.toJson()));
              },
            );
            itemWidget = Card(margin: EdgeInsets.zero, child: itemWidget);
            break;
          case 'discovery':
            itemWidget = _DiscoveryActivityItem(data: item.data!);
            break;
          default:
            itemWidget = const Placeholder();
        }

        return itemWidget;
      },
    );
  }
}
