import 'dart:async';

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

import '../i18n/strings.g.dart';
import '../services/message_store.dart';
import '../services/social_service.dart';
import '../services/social_settings.dart';
import '../state/messages_cubit.dart';
import '../state/trust_cubit.dart';
import 'theme.dart';

/// A 1:1 encrypted chat with one peer (redesign screen 10). Private and
/// metadata-hiding (NIP-17) under the hood; local-first, so it degrades to a
/// "set up sharing" note when there's no relay.
class ChatScreen extends StatefulWidget {
  const ChatScreen({
    required this.social,
    required this.settings,
    required this.peerPubkey,
    this.messageStore,
    super.key,
  });

  final SocialService social;
  final SocialSettings settings;
  final String peerPubkey;

  /// Optional persistence for chat history (keystore-backed); null in tests.
  final MessageStore? messageStore;

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  SocialSession? _session;
  MessagesCubit? _messages;
  TrustCubit? _trust;
  bool _loading = true;
  final _input = TextEditingController();

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

  Future<void> _init() async {
    // One session for this chat carries both messaging and trust (the shared-
    // connection shape). Offline (no relays / unreachable) → null transports.
    final relays = await widget.settings.relayUrls();
    SocialSession? session;
    if (relays.isNotEmpty) {
      try {
        session = await widget.social.openSession(relays);
      } catch (_) {
        session = null;
      }
    }
    if (!mounted) {
      await session?.close();
      return;
    }
    final self = widget.social.publicKeyHex;
    final messages = MessagesCubit(
      session?.messages,
      peerPubkey: widget.peerPubkey,
      selfPubkey: self,
      store: widget.messageStore,
    )..start();
    final trust = TrustCubit(session?.trust,
        peerPubkey: widget.peerPubkey, selfPubkey: self);
    unawaited(trust.load());
    setState(() {
      _session = session;
      _messages = messages;
      _trust = trust;
      _loading = false;
    });
  }

  Future<void> _send() async {
    final cubit = _messages;
    if (cubit == null || _input.text.trim().isEmpty) return;
    final text = _input.text;
    _input.clear();
    await cubit.send(text);
  }

  @override
  void dispose() {
    _messages?.close();
    _trust?.close();
    _session?.close();
    _input.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final t = context.t;
    final messages = _messages;
    final trust = _trust;
    return Scaffold(
      appBar: AppBar(title: Text(t.chat.title)),
      body: _loading || messages == null || trust == null
          ? const Center(child: CircularProgressIndicator())
          : MultiBlocProvider(
              providers: [
                BlocProvider.value(value: messages),
                BlocProvider.value(value: trust),
              ],
              child: _ChatBody(controller: _input, onSend: _send),
            ),
    );
  }
}

class _ChatBody extends StatelessWidget {
  const _ChatBody({required this.controller, required this.onSend});

  final TextEditingController controller;
  final Future<void> Function() onSend;

  @override
  Widget build(BuildContext context) {
    final t = context.t;
    final cubit = context.read<MessagesCubit>();
    if (!cubit.isOnline) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(32),
          child: Text(
            t.chat.offline,
            textAlign: TextAlign.center,
            style: const TextStyle(color: seedMuted, fontSize: 15),
          ),
        ),
      );
    }
    return Column(
      children: [
        const _TrustBanner(),
        Expanded(
          child: BlocBuilder<MessagesCubit, ChatState>(
            builder: (context, state) {
              if (state.messages.isEmpty) {
                return Center(
                  child: Text(t.chat.empty,
                      style: const TextStyle(color: seedMuted)),
                );
              }
              return ListView.builder(
                padding: const EdgeInsets.all(12),
                itemCount: state.messages.length,
                itemBuilder: (context, i) {
                  final m = state.messages[i];
                  return _Bubble(text: m.text, mine: cubit.isMine(m));
                },
              );
            },
          ),
        ),
        _Composer(controller: controller, onSend: onSend),
      ],
    );
  }
}

/// A slim "web of trust" strip: how many vouch for this peer, and a toggle to
/// add/remove your own vouch ("I know this person").
class _TrustBanner extends StatelessWidget {
  const _TrustBanner();

  @override
  Widget build(BuildContext context) {
    final t = context.t;
    return BlocBuilder<TrustCubit, TrustState>(
      builder: (context, state) {
        final cubit = context.read<TrustCubit>();
        if (!cubit.isOnline || state.loading) return const SizedBox.shrink();
        final known = state.knownToYou;
        return Container(
          width: double.infinity,
          color: seedPrimaryContainer.withValues(alpha: 0.5),
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          child: Row(
            children: [
              Icon(
                known ? Icons.verified : Icons.verified_user_outlined,
                size: 18,
                color: seedGreen,
              ),
              const SizedBox(width: 8),
              Expanded(
                child: Text(
                  known
                      ? t.trust.circle
                      : state.certifierCount == 0
                          ? t.trust.none
                          : t.trust.count(n: state.certifierCount),
                  style: TextStyle(
                    color: known ? seedGreen : seedOnSurface,
                    fontSize: 13,
                    fontWeight: known ? FontWeight.w600 : FontWeight.w400,
                  ),
                ),
              ),
              TextButton(
                key: const Key('chat.vouch'),
                onPressed: state.busy ? null : cubit.toggleVouch,
                child: Text(state.iVouch ? t.trust.vouched : t.trust.vouch),
              ),
            ],
          ),
        );
      },
    );
  }
}

class _Bubble extends StatelessWidget {
  const _Bubble({required this.text, required this.mine});

  final String text;
  final bool mine;

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: mine ? AlignmentDirectional.centerEnd : AlignmentDirectional.centerStart,
      child: Container(
        margin: const EdgeInsets.symmetric(vertical: 4),
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
        constraints: BoxConstraints(
          maxWidth: MediaQuery.of(context).size.width * 0.75,
        ),
        decoration: BoxDecoration(
          color: mine ? seedGreen : seedPrimaryContainer,
          borderRadius: BorderRadius.circular(16),
        ),
        child: Text(
          text,
          style: TextStyle(
            color: mine ? Colors.white : seedOnSurface,
            fontSize: 15,
          ),
        ),
      ),
    );
  }
}

class _Composer extends StatelessWidget {
  const _Composer({required this.controller, required this.onSend});

  final TextEditingController controller;
  final Future<void> Function() onSend;

  @override
  Widget build(BuildContext context) {
    final t = context.t;
    return SafeArea(
      top: false,
      child: Padding(
        padding: const EdgeInsets.fromLTRB(12, 6, 12, 12),
        child: Row(
          children: [
            Expanded(
              child: TextField(
                key: const Key('chat.input'),
                controller: controller,
                textInputAction: TextInputAction.send,
                onSubmitted: (_) => onSend(),
                decoration: InputDecoration(
                  hintText: t.chat.hint,
                  filled: true,
                  fillColor: seedField,
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(24),
                    borderSide: BorderSide.none,
                  ),
                  contentPadding:
                      const EdgeInsets.symmetric(horizontal: 18, vertical: 10),
                ),
              ),
            ),
            const SizedBox(width: 8),
            IconButton.filled(
              key: const Key('chat.send'),
              icon: const Icon(Icons.send),
              tooltip: t.chat.send,
              onPressed: onSend,
            ),
          ],
        ),
      ),
    );
  }
}
