import 'dart:async';

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

import '../i18n/strings.g.dart';
import '../services/inbox_service.dart';
import '../services/message_store.dart';
import '../services/profile_cache.dart';
import '../services/social_connection.dart';
import 'theme.dart';
import 'unread_badge.dart';

/// The messages inbox: past conversations, newest first. Shows each peer's
/// published name (falling back to a short key), and opens the chat on tap.
class ChatListScreen extends StatefulWidget {
  const ChatListScreen({
    required this.store,
    this.connection,
    this.profileCache,
    this.inbox,
    super.key,
  });

  final MessageStore store;

  /// The shared relay connection, for resolving peers' published names.
  final SocialConnection? connection;
  final ProfileCache? profileCache;

  /// App-wide inbox listener; the list reloads whenever it reports a change.
  final InboxService? inbox;

  @override
  State<ChatListScreen> createState() => _ChatListScreenState();
}

class _ChatListScreenState extends State<ChatListScreen> {
  List<ChatSummary>? _items;
  final Map<String, String> _names = {};
  StreamSubscription<void>? _changesSub;

  @override
  void initState() {
    super.initState();
    _load();
    // Live-refresh when the app-wide inbox listener persists a new message.
    _changesSub = widget.inbox?.changes.listen((_) => _load());
  }

  @override
  void dispose() {
    _changesSub?.cancel();
    super.dispose();
  }

  Future<void> _load() async {
    final items = await widget.store.conversations();
    final cache = widget.profileCache;
    if (cache != null) {
      for (final c in items) {
        final name = await cache.name(c.peerPubkey);
        if (name != null) _names[c.peerPubkey] = name;
      }
    }
    if (!mounted) return;
    setState(() => _items = items);
    unawaited(_resolveMissingNames(items));
  }

  /// Fetches published names for peers we don't have cached yet, over the shared
  /// connection. Best effort; the list already shows short keys meanwhile.
  Future<void> _resolveMissingNames(List<ChatSummary> items) async {
    final connection = widget.connection;
    final cache = widget.profileCache;
    if (connection == null || cache == null) return;
    final missing =
        items.map((c) => c.peerPubkey).where((p) => !_names.containsKey(p));
    if (missing.isEmpty) return;
    final session = await connection.session();
    if (session == null) return;
    try {
      for (final peer in missing) {
        final profile = await session.profile.fetch(peer);
        if (profile != null && profile.name.isNotEmpty) {
          await cache.setName(peer, profile.name);
          if (mounted) setState(() => _names[peer] = profile.name);
        }
      }
    } catch (_) {
      // offline / unreachable — short keys stay.
    }
  }

  @override
  Widget build(BuildContext context) {
    final t = context.t;
    final items = _items;
    return Scaffold(
      appBar: AppBar(title: Text(t.chatList.title)),
      body: items == null
          ? const Center(child: CircularProgressIndicator())
          : items.isEmpty
              ? Center(
                  child: Padding(
                    padding: const EdgeInsets.all(32),
                    child: Text(
                      t.chatList.empty,
                      textAlign: TextAlign.center,
                      style: const TextStyle(color: seedMuted, fontSize: 15),
                    ),
                  ),
                )
              : ListView.separated(
                  itemCount: items.length,
                  separatorBuilder: (_, _) => const Divider(height: 1),
                  itemBuilder: (context, i) {
                    final c = items[i];
                    return ListTile(
                      leading: UnreadBadge(
                        peer: c.peerPubkey,
                        child: const CircleAvatar(
                          backgroundColor: seedAvatar,
                          child: Icon(Icons.person, color: seedOnAvatar),
                        ),
                      ),
                      title: Text(_names[c.peerPubkey] ??
                          shortPubkey(c.peerPubkey)),
                      subtitle: Text(
                        c.lastText,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                      onTap: () => context.push('/chat/${c.peerPubkey}'),
                    );
                  },
                ),
    );
  }
}
