import 'package:logging/logging.dart';

import '../../globals.dart';
import '../../models/user_notification.dart';
import '../../services/connections_manager.dart';
import '../../utils/active_profile_selector.dart';
import '../../utils/dateutils.dart';
import '../../utils/html_to_edit_text_helper.dart';
import '../../utils/string_utils.dart';
import 'connection_mastodon_extensions.dart';
import 'timeline_entry_mastodon_extensions.dart';

final _logger = Logger('NotificationMastodonExtension');

extension NotificationMastodonExtension on UserNotification {
  static UserNotification fromJson(Map<String, dynamic> json) {
    final int timestamp = json.containsKey('created_at')
        ? OffsetDateTimeUtils.epochSecTimeFromTimeZoneString(json['created_at'])
            .fold(
                onSuccess: (value) => value,
                onError: (error) {
                  _logger.severe("Couldn't read date time string: $error");
                  return 0;
                })
        : 0;

    final type = NotificationType.parse(json['type']);
    final from = ConnectionMastodonExtensions.fromJson(json['account']);
    getIt<ActiveProfileSelector<ConnectionsManager>>()
        .activeEntry
        .andThenSuccess((manager) => manager.upsertConnection(from));
    var statusId = '';
    var statusLink = '';
    var content = '';
    switch (type) {
      case NotificationType.follow:
        content = '${from.name}(${from.handle})  is now following you';
        break;
      case NotificationType.follow_request:
        content = '${from.name}(${from.handle})  submitted a follow request ';
        break;
      case NotificationType.unknown:
        content = '${from.name} has unknown interaction notification';
        break;
      case NotificationType.reshare:
      case NotificationType.reblog:
      case NotificationType.favourite:
      case NotificationType.mention:
      case NotificationType.status:
        final status = TimelineEntryMastodonExtensions.fromJson(json['status']);
        statusId = status.id;
        statusLink = status.externalLink;
        final referenceType = type == NotificationType.mention
            ? ''
            : status.parentId.isEmpty
                ? 'post'
                : 'comment';
        final baseContent = type == NotificationType.mention
            ? "${from.name} ${type.toVerb()}"
            : "${from.name} ${type.toVerb()} ${status.author}'s";
        final bodyText = htmlToSimpleText(status.body).truncate(length: 100);
        content = "$baseContent $referenceType: $bodyText";
        break;
      case NotificationType.direct_message:
        // this is a Relatica internal type so nothing to do here
        break;
    }

    return UserNotification(
      id: json['id'].toString(),
      type: type,
      fromId: from.id,
      fromName: from.name,
      fromUrl: from.profileUrl.toString(),
      timestamp: timestamp,
      iid: statusId,
      dismissed: json['dismissed'] ?? false,
      content: content,
      link: statusLink,
    );
  }
}
