part of '../message_group.dart';

class _HoverActions extends StatefulWidget {
  final PyramidTheme pt;
  final Event event;
  final List<Event> events;
  final Room? room;
  final String currentUserId;
  final VoidCallback? onReply;
  final ValueChanged<bool>? onOverlayStateChanged;

  const _HoverActions({
    required this.pt,
    required this.event,
    required this.events,
    required this.currentUserId,
    this.room,
    this.onReply,
    this.onOverlayStateChanged,
  });

  @override
  State<_HoverActions> createState() => _HoverActionsState();
}

class _HoverActionsState extends State<_HoverActions> {
  OverlayEntry? _reactionOverlay;
  List<String> _quickReactions = ReactionService.quickReactions;

  @override
  void initState() {
    super.initState();
    ReactionService.load().then((_) {
      if (mounted) setState(() => _quickReactions = ReactionService.quickReactions);
    });
  }

  void _closeReactionOverlay() {
    _reactionOverlay?.remove();
    _reactionOverlay = null;
    widget.onOverlayStateChanged?.call(false);
  }

  void _toggleReactionPicker() {
    if (_reactionOverlay != null) {
      _closeReactionOverlay();
      return;
    }

    final box = context.findRenderObject() as RenderBox?;
    final offset = box?.localToGlobal(Offset.zero) ?? Offset.zero;

    _reactionOverlay = OverlayEntry(builder: (ctx) {
      final screenSize = MediaQuery.sizeOf(ctx);
      const pickerW = 340.0;
      const pickerH = 380.0;
      double left = (offset.dx - pickerW / 2).clamp(8.0, screenSize.width - pickerW - 8);
      double top = (offset.dy - pickerH - 8).clamp(8.0, screenSize.height - pickerH - 8);

      return Material(
        type: MaterialType.transparency,
        child: Stack(children: [
          GestureDetector(
            onTap: _closeReactionOverlay,
            behavior: HitTestBehavior.translucent,
            child: const SizedBox.expand(),
          ),
          Positioned(
            left: left,
            top: top,
            child: EmojiPicker(
              onEmojiSelected: (emoji) {
                _closeReactionOverlay();
                widget.room?.sendReaction(widget.event.eventId, emoji)
                    .catchError((_) => '');
                ReactionService.recordUsed(emoji).then((_) {
                  if (mounted) setState(() => _quickReactions = ReactionService.quickReactions);
                });
              },
              onClose: _closeReactionOverlay,
            ),
          ),
        ]),
      );
    });
    widget.onOverlayStateChanged?.call(true);
    Overlay.of(context).insert(_reactionOverlay!);
  }

  void _showMoreMenu() {
    final box = context.findRenderObject() as RenderBox?;
    final offset = box?.localToGlobal(Offset.zero) ?? Offset.zero;
    final size = box?.size ?? Size.zero;

    final isOwnMessage = widget.event.senderId == widget.currentUserId;
    final text = widget.event.body;

    // Find any image or sticker event in the group that can be saved as a sticker.
    final imageEvent = widget.events.firstWhereOrNull(
      (e) => e.messageType == 'm.image' || e.type == EventTypes.Sticker,
    );

    // Capture messenger synchronously before showMenu's async gap so the
    // snackbar can be shown even if the widget is unmounted by then.
    final messenger = ScaffoldMessenger.maybeOf(context);

    showMenu<String>(
      context: context,
      position: RelativeRect.fromLTRB(
        offset.dx, offset.dy - size.height,
        offset.dx + size.width, offset.dy,
      ),
      items: [
        PopupMenuItem(value: 'copy', child: Row(children: [
          Icon(Icons.copy_rounded, size: 16, color: widget.pt.fgMuted),
          const SizedBox(width: 10),
          Text('Kopieren', style: TextStyle(color: widget.pt.fg, fontSize: 14)),
        ])),
        if (imageEvent != null)
          PopupMenuItem(value: 'save_sticker', child: Row(children: [
            Icon(Icons.sticky_note_2_outlined, size: 16, color: widget.pt.fgMuted),
            const SizedBox(width: 10),
            Text('Als Sticker speichern', style: TextStyle(color: widget.pt.fg, fontSize: 14)),
          ])),
        if (isOwnMessage)
          PopupMenuItem(value: 'delete', child: Row(children: [
            Icon(Icons.delete_outline_rounded, size: 16, color: widget.pt.danger),
            const SizedBox(width: 10),
            Text('Löschen', style: TextStyle(color: widget.pt.danger, fontSize: 14)),
          ])),
        PopupMenuItem(value: 'pin', child: Row(children: [
          Icon(Icons.push_pin_outlined, size: 16, color: widget.pt.fgMuted),
          const SizedBox(width: 10),
          Text('Anpinnen', style: TextStyle(color: widget.pt.fg, fontSize: 14)),
        ])),
      ],
    ).then((value) async {
      if (value == 'copy') {
        Clipboard.setData(ClipboardData(text: text));
      } else if (value == 'save_sticker' && imageEvent != null) {
        final ok = await GifFavoriteService.addImageAsStickerFavorite(imageEvent);
        messenger?.showSnackBar(SnackBar(
          content: Text(ok ? 'Als Sticker gespeichert' : 'Fehler beim Speichern'),
          duration: const Duration(seconds: 2),
        ));
      } else if (value == 'delete') {
        widget.event.redactEvent(reason: 'Vom Nutzer gelöscht')
            .catchError((_) => null);
      } else if (value == 'pin') {
        final room = widget.room;
        if (room == null) return;
        final pinned = List<String>.from(
          room.getState(EventTypes.RoomPinnedEvents)?.content['pinned'] as List? ?? [],
        );
        final eventId = widget.event.eventId;
        if (!pinned.contains(eventId)) pinned.add(eventId);
        room.setPinnedEvents(pinned).catchError((_) => '');
      }
    });
  }

  @override
  void dispose() {
    if (_reactionOverlay != null) {
      _reactionOverlay!.remove();
      _reactionOverlay = null;
      widget.onOverlayStateChanged?.call(false);
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    return Container(
      padding: const EdgeInsets.all(2),
      decoration: BoxDecoration(
        color: pt.bg0,
        borderRadius: BorderRadius.circular(pt.rBase),
        border: Border.all(color: pt.border),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withAlpha(100),
            blurRadius: 12,
            offset: const Offset(0, 4),
          ),
        ],
      ),
      child: Row(
        children: [
          // Quick reactions
          ..._quickReactions.map((emoji) => _QuickReactionBtn(
            emoji: emoji,
            pt: pt,
            onTap: () {
              widget.room?.sendReaction(widget.event.eventId, emoji)
                  .catchError((_) => '');
              ReactionService.recordUsed(emoji).then((_) {
                if (mounted) setState(() => _quickReactions = ReactionService.quickReactions);
              });
            },
          )),
          Container(width: 1, height: 18, color: pt.border, margin: const EdgeInsets.symmetric(horizontal: 2)),
          _ActionBtn(
            icon: Icons.add_reaction_outlined,
            tooltip: 'Reaktion',
            pt: pt,
            accent: true,
            onTap: _toggleReactionPicker,
          ),
          _ActionBtn(
            icon: Icons.reply_rounded,
            tooltip: 'Antworten',
            pt: pt,
            onTap: widget.onReply,
          ),
          _ActionBtn(
            icon: Icons.more_horiz_rounded,
            tooltip: 'Mehr',
            pt: pt,
            onTap: _showMoreMenu,
          ),
        ],
      ),
    );
  }
}

class _ActionBtn extends StatefulWidget {
  final IconData icon;
  final String tooltip;
  final PyramidTheme pt;
  final bool accent;
  final VoidCallback? onTap;

  const _ActionBtn({
    required this.icon,
    required this.tooltip,
    required this.pt,
    this.accent = false,
    this.onTap,
  });

  @override
  State<_ActionBtn> createState() => _ActionBtnState();
}

class _ActionBtnState extends State<_ActionBtn> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final color = _hovered
        ? (widget.accent ? widget.pt.accent : widget.pt.fg)
        : widget.pt.fgMuted;

    return MouseRegion(
      cursor: SystemMouseCursors.click,
      onEnter: (_) => setState(() => _hovered = true),
      onExit: (_) => setState(() => _hovered = false),
      child: GestureDetector(
        onTap: widget.onTap,
        child: Tooltip(
          message: widget.tooltip,
          waitDuration: const Duration(milliseconds: 400),
          child: AnimatedContainer(
            duration: const Duration(milliseconds: 120),
            width: 32,
            height: 32,
            decoration: BoxDecoration(
              color: _hovered ? widget.pt.bgHover : Colors.transparent,
              borderRadius: BorderRadius.circular(widget.pt.rSm),
            ),
            child: Center(
              child: Icon(widget.icon, size: 16, color: color),
            ),
          ),
        ),
      ),
    );
  }
}
