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

import '../../../../api/marianumcloud/talk/chat/get_chat_response.dart';
import '../../../../api/marianumcloud/talk/chat/rich_object_string_processor.dart';
import '../../../../model/account_data.dart';
import '../../../../model/endpoint_data.dart';
import '../../../../utils/emoji_detection.dart';
import '../../../../utils/url_opener.dart';
import '../widgets/highlighted_linkify.dart';
import '../widgets/message_markdown.dart';

class ChatMessage {
  String originalMessage;
  Map<String, RichObjectString>? originalData;

  RichObjectString? file;
  String content = '';

  ChatMessage({required this.originalMessage, this.originalData}) {
    if (originalData?.containsKey('file') ?? false) {
      file = originalData?['file'];
    }
    content = RichObjectStringProcessor.parseToString(
      originalMessage,
      originalData,
    );
  }

  Widget getWidget({
    String? highlightQuery,
    TextStyle? style,
    bool renderMarkdown = false,
  }) {
    final emojiFontSize = standaloneEmojiFontSize(content);
    final effectiveStyle = emojiFontSize == null
        ? style
        : (style ?? const TextStyle()).copyWith(
            fontSize: emojiFontSize,
            height: 1.15,
          );

    // Markdown replaces the plain linkified text only for regular messages.
    // Emoji-only bodies keep their enlarged rendering, and while searching we
    // fall back to the linkify path so matches can still be highlighted (the
    // search highlight can't be threaded through Markdown formatting).
    final hasQuery = highlightQuery?.trim().isNotEmpty ?? false;
    final useMarkdown = renderMarkdown && emojiFontSize == null && !hasQuery;

    var contentWidget = useMarkdown
        ? MessageMarkdown(data: content, style: effectiveStyle)
        : HighlightedLinkify(
            text: content,
            onOpen: UrlOpener.onOpen,
            highlight: highlightQuery,
            style: effectiveStyle,
          );

    // Enlarged emoji glyphs otherwise sit flush against the bubble edges.
    if (emojiFontSize != null) {
      contentWidget = Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6),
        child: contentWidget,
      );
    }

    if (originalData?['object']?.type == RichObjectStringObjectType.talkPoll) {
      return ListTile(
        leading: const Icon(Icons.poll_outlined),
        title: Text(originalData!['object']!.name),
        contentPadding: const EdgeInsets.only(left: 10),
      );
    }

    if (file == null) return contentWidget;

    return Padding(
      padding: const EdgeInsets.only(top: 5),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          CachedNetworkImage(
            errorWidget: (context, url, error) => Row(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Icon(Icons.file_open_outlined, size: 35),
                const SizedBox(width: 10),
                Flexible(
                  child: Text(
                    file!.name,
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(fontWeight: FontWeight.bold),
                  ),
                ),
                const SizedBox(width: 10),
              ],
            ),
            alignment: Alignment.center,
            placeholder: (context, url) => const Padding(
              padding: EdgeInsets.all(15),
              child: SizedBox(width: 50, child: LinearProgressIndicator()),
            ),
            fadeInDuration: Duration.zero,
            fadeOutDuration: Duration.zero,
            errorListener: (value) {},
            httpHeaders: AccountData().authHeaders(),
            imageUrl:
                'https://${EndpointData().nextcloud().full()}/index.php/core/preview?fileId=${file!.id}&x=130&y=-1&a=1',
          ),
          if (originalMessage != '{file}') ...[
            SizedBox(height: 5),
            contentWidget,
          ],
        ],
      ),
    );
  }
}
