import 'dart:async';

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

import '../../../../api/marianumcloud/talk/actions/talk_actions.dart';
import '../../../../api/marianumcloud/talk/chat/rich_object_string_processor.dart';
import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
import '../../../../api/marianumcloud/talk/set_read_marker/set_read_marker.dart';
import '../../../../extensions/date_time.dart';
import '../../../../model/account_data.dart';
import '../../../../notification/notification_tasks.dart';
import '../../../../routing/app_routes.dart';
import '../../../../state/app/modules/chat/bloc/chat_bloc.dart';
import '../../../../state/app/modules/chat_list/bloc/chat_list_bloc.dart';
import '../../../../utils/haptics.dart';
import '../../../../widget/a11y/a11y_labels.dart';
import '../../../../widget/async_action_button.dart';
import '../../../../widget/confirm_dialog.dart';
import '../../../../widget/debug/debug_tile.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/user_avatar.dart';
import '../data/talk_markdown.dart';
import '../talk_navigator.dart';

class ChatTile extends StatefulWidget {
  final GetRoomResponseObject data;
  final bool disableContextActions;
  final bool hasDraft;

  /// When set, replaces the default tap-into-chat behaviour. Used by the
  /// share-intent picker to surface the room selection without opening the
  /// chat view itself.
  final void Function(GetRoomResponseObject room)? onTapOverride;

  const ChatTile({
    super.key,
    required this.data,
    this.disableContextActions = false,
    this.hasDraft = false,
    this.onTapOverride,
  });

  @override
  State<ChatTile> createState() => _ChatTileState();
}

class _ChatTileState extends State<ChatTile> {
  String? selfUsername;

  @override
  void initState() {
    super.initState();
    AccountData().waitForPopulation().then((_) {
      if (!mounted) return;
      setState(
        () => selfUsername = AccountData().isPopulated()
            ? AccountData().getUsername()
            : null,
      );
    });
  }

  void _refreshList() => context.read<ChatListBloc>().refresh();

  /// One-line preview of the last message: rich-object placeholders resolved,
  /// newlines flattened and — for Markdown messages — formatting stripped so
  /// the list shows readable text rather than raw markers.
  String _lastMessagePreview() {
    final last = widget.data.lastMessage;
    final text = RichObjectStringProcessor.parseToString(
      last.message.replaceAll('\n', ' '),
      last.messageParameters,
    );
    return last.markdown ? markdownToPlainText(text) : text;
  }

  Future<void> _setCurrentAsRead() async {
    final token = widget.data.token;
    final lastId = widget.data.lastMessage.id;
    context.read<ChatListBloc>().markRoomAsRead(token, lastId);
    unawaited(NotificationTasks.clearNotificationsForChat(token));
    await context.read<ChatBloc>().sendServerReadMarker(token, lastId);
    if (!mounted) return;
    _refreshList();
  }

  @override
  Widget build(BuildContext context) {
    final chatBloc = context.watch<ChatBloc>();
    final isGroup =
        widget.data.type != GetRoomResponseObjectConversationType.oneToOne;
    final circleAvatar = UserAvatar(
      id: isGroup ? widget.data.token : widget.data.name,
      isGroup: isGroup,
    );

    return ListTile(
      style: ListTileStyle.list,
      tileColor:
          chatBloc.state.data?.currentToken == widget.data.token &&
              TalkNavigator.isSecondaryVisible(context)
          ? Theme.of(context).primaryColor.withAlpha(100)
          : null,
      leading: Stack(
        children: [
          // Der Name steht bereits im Titel der Zeile – das Avatarbild selbst
          // muss der Screenreader nicht ansagen. Nur bei Gruppen ist der
          // Hinweis „Gruppe" nützlich (sonst nicht vom Einzelchat zu
          // unterscheiden).
          Semantics(
            label: isGroup ? A11yLabels.group : null,
            child: ExcludeSemantics(child: circleAvatar),
          ),
          Visibility(
            visible: widget.data.isFavorite,
            child: Positioned(
              right: 0,
              bottom: 0,
              child: Container(
                padding: const EdgeInsets.all(1),
                decoration: BoxDecoration(
                  color: Theme.of(context).primaryColor.withAlpha(200),
                  borderRadius: BorderRadius.circular(90.0),
                ),
                child: const Icon(
                  Icons.star,
                  color: Colors.amberAccent,
                  size: 15,
                  semanticLabel: A11yLabels.favorite,
                ),
              ),
            ),
          ),
        ],
      ),
      title: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Flexible(
            child: Text(
              widget.data.displayName,
              overflow: TextOverflow.ellipsis,
            ),
          ),
          if (widget.hasDraft) ...[
            const SizedBox(width: 5),
            const Icon(
              Icons.edit_outlined,
              size: 15,
              semanticLabel: A11yLabels.draft,
            ),
          ],
        ],
      ),
      subtitle: Text(
        '${DateTime.fromMillisecondsSinceEpoch(widget.data.lastMessage.timestamp * 1000).formatRelative()}: '
        '${_lastMessagePreview()}',
        overflow: TextOverflow.ellipsis,
      ),
      trailing: widget.data.unreadMessages <= 0
          ? null
          : Semantics(
              label: '${widget.data.unreadMessages} ${A11yLabels.unread}',
              child: ExcludeSemantics(
                child: Container(
                  padding: const EdgeInsets.all(1),
                  decoration: BoxDecoration(
                    color: Theme.of(context).primaryColor,
                    borderRadius: BorderRadius.circular(30),
                  ),
                  constraints: const BoxConstraints(
                    minWidth: 20,
                    minHeight: 20,
                  ),
                  child: Text(
                    '${widget.data.unreadMessages}',
                    style: const TextStyle(color: Colors.white, fontSize: 15),
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
            ),
      onTap: () {
        if (widget.onTapOverride != null) {
          widget.onTapOverride!(widget.data);
          return;
        }
        if (selfUsername == null) return;
        // openChatView is the single entry point for opening a chat —
        // it handles optimistic mark-as-read, tray cleanup, push, and
        // setToken in one place so the notification-tap path gets the
        // same treatment as a tile tap.
        AppRoutes.openChatView(
          context,
          room: widget.data,
          selfId: selfUsername!,
          avatar: circleAvatar,
          overrideToSingleSubScreen: true,
        );
      },
      onLongPress: () {
        if (widget.disableContextActions) return;
        Haptics.longPress();
        showDetailsBottomSheet(
          context,
          children: (sheetCtx) => [
            if (widget.data.unreadMessages > 0)
              AsyncListTile(
                leading: const Icon(Icons.mark_chat_read_outlined),
                title: const Text('Als gelesen markieren'),
                onPressed: _setCurrentAsRead,
              )
            else
              AsyncListTile(
                leading: const Icon(Icons.mark_chat_unread_outlined),
                title: const Text('Als ungelesen markieren'),
                onPressed: () async {
                  await SetReadMarker(widget.data.token, false).run();
                  if (mounted) _refreshList();
                },
              ),
            if (widget.data.isFavorite)
              AsyncListTile(
                leading: const Icon(Icons.stars_outlined),
                title: const Text('Von Favoriten entfernen'),
                onPressed: () async {
                  await SetFavorite(widget.data.token, false).run();
                  if (mounted) _refreshList();
                },
              )
            else
              AsyncListTile(
                leading: const Icon(Icons.star_outline),
                title: const Text('Zu Favoriten hinzufügen'),
                onPressed: () async {
                  await SetFavorite(widget.data.token, true).run();
                  if (mounted) _refreshList();
                },
              ),
            ListTile(
              leading: const Icon(Icons.delete_outline),
              title: const Text('Talk-Chat verlassen'),
              onTap: () {
                Navigator.of(sheetCtx).pop();
                ConfirmDialog(
                  title: 'Talk-Chat verlassen',
                  content:
                      'Du benötigst ggf. eine Einladung um erneut beizutreten.',
                  confirmButton: 'Verlassen',
                  onConfirmAsync: () async {
                    await LeaveRoom(widget.data.token).run();
                    if (mounted) _refreshList();
                  },
                ).asDialog(context);
              },
            ),
            DebugTile(sheetCtx).jsonData(widget.data.toJson()),
          ],
        );
      },
    );
  }
}
