import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_split_view/flutter_split_view.dart';

import '../../../routing/app_routes.dart';
import '../../../state/app/infrastructure/loadable_state/loadable_state.dart';
import '../../../state/app/infrastructure/loadable_state/view/loadable_state_consumer.dart';
import '../../../state/app/modules/chat_list/bloc/chat_list_bloc.dart';
import '../../../state/app/modules/chat_list/bloc/chat_list_state.dart';
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../widget/demo_restricted.dart';
import '../../../widget/placeholder_view.dart';
import 'data/open_direct_chat.dart';
import 'join_chat.dart';
import 'notification_permission_prompt.dart';
import 'search_chat.dart';
import 'widgets/chat_tile.dart';
import 'widgets/split_view_placeholder.dart';

// Reads from the global ChatListBloc in main.dart — re-providing a local
// one here would shadow it and split the state in two.
class ChatList extends StatelessWidget {
  const ChatList({super.key});

  @override
  Widget build(BuildContext context) => const _ChatListView();
}

class _ChatListView extends StatefulWidget {
  const _ChatListView();

  @override
  State<_ChatListView> createState() => _ChatListViewState();
}

class _ChatListViewState extends State<_ChatListView> {
  late final SettingsCubit _settings;

  @override
  void initState() {
    super.initState();
    _settings = context.read<SettingsCubit>();

    AppRoutes.pendingChatToken.addListener(_maybeOpenPendingChat);

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) return;
      _maybeOpenPendingChat();
      unawaited(maybePromptTalkNotifications(context));
    });
  }

  @override
  void dispose() {
    AppRoutes.pendingChatToken.removeListener(_maybeOpenPendingChat);
    super.dispose();
  }

  void _maybeOpenPendingChat() {
    if (!mounted) return;
    final resolved = AppRoutes.resolvePendingChat(context);
    if (resolved == null) return;
    AppRoutes.pendingChatToken.value = null;
    AppRoutes.openChatView(
      context,
      room: resolved.room,
      selfId: resolved.selfId,
      avatar: resolved.avatar,
      overrideToSingleSubScreen: true,
    );
  }

  @override
  Widget build(BuildContext context) {
    final bloc = context.read<ChatListBloc>();
    return SplitView.material(
      placeholder: const SplitViewPlaceholder(),
      breakpoint: 1000,
      child: BlocListener<ChatListBloc, LoadableState<ChatListState>>(
        listener: (_, _) => _maybeOpenPendingChat(),
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Talk'),
            actions: [
              IconButton(
                tooltip: 'Suchen',
                icon: const Icon(Icons.search),
                onPressed: () {
                  final rooms = bloc.state.data?.rooms;
                  if (rooms == null) return;
                  showSearch(
                    context: context,
                    delegate: SearchChat(
                      rooms.data.toList(),
                      onStartChat: (username, displayName) =>
                          openOrCreateDirectChat(
                            context,
                            actorId: username,
                            actorDisplayName: displayName,
                          ),
                    ),
                  );
                },
              ),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            heroTag: 'createChat',
            backgroundColor: Theme.of(context).primaryColor,
            onPressed: () {
              if (guardDemoAction(context)) return;
              showSearch(context: context, delegate: JoinChat()).then((
                username,
              ) {
                if (username == null || !context.mounted) return;
                openOrCreateDirectChat(
                  context,
                  actorId: username,
                  actorDisplayName: username,
                );
              });
            },
            child: const Icon(Icons.add_comment_outlined),
          ),
          body: LoadableStateConsumer<ChatListBloc, ChatListState>(
            child: (state, _) {
              final rooms = state.rooms;
              if (rooms == null) return const SizedBox.shrink();

              final talkSettings = context
                  .watch<SettingsCubit>()
                  .val()
                  .talkSettings;
              final sorted = rooms.sortBy(
                favoritesToTop: talkSettings.sortFavoritesToTop,
                unreadToTop: talkSettings.sortUnreadToTop,
              );

              if (sorted.isEmpty) {
                return const PlaceholderView(
                  icon: Icons.chat_bubble_outline,
                  text: 'Noch keine Chats — starte einen über das +-Symbol.',
                );
              }

              return ListView(
                padding: EdgeInsets.zero,
                children: sorted.map((room) {
                  final hasDraft = _settings
                      .val()
                      .talkSettings
                      .drafts
                      .containsKey(room.token);
                  // Stable key keeps element identity across re-sorts so the
                  // inner UserAvatar reuses its cached bytes instead of
                  // flashing on every list update.
                  return ChatTile(
                    key: ValueKey(room.token),
                    data: room,
                    hasDraft: hasDraft,
                  );
                }).toList(),
              );
            },
          ),
        ),
      ),
    );
  }
}
