import 'dart:convert';

import 'package:PiliPlus/common/assets.dart';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/flutter/list_tile.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart'
    show Session, SessionId, SessionPageType, SessionType, UnreadStyle;
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/pages/whisper_secondary/view.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';

class WhisperSessionItem extends StatelessWidget {
  const WhisperSessionItem({
    super.key,
    required this.item,
    required this.onSetTop,
    required this.onSetMute,
    required this.onRemove,
  });

  final Session item;
  final Function(bool isTop, SessionId id) onSetTop;
  final Function(bool isMuted, Int64 talkerUid) onSetMute;
  final ValueChanged<int> onRemove;

  @override
  Widget build(BuildContext context) {
    final resource =
        item.sessionInfo.avatar.fallbackLayers.layers.first.resource;
    final avatar = resource.hasResImage()
        ? resource.resImage.imageSrc.remote.url
        : resource.hasResAnimation()
        ? resource.resAnimation.webpSrc.remote.url
        : resource.resNativeDraw.drawSrc.remote.url;
    Map? vipInfo = item.sessionInfo.hasVipInfo()
        ? jsonDecode(item.sessionInfo.vipInfo)
        : null;
    final ThemeData theme = Theme.of(context);

    return ListTile(
      safeArea: true,
      tileColor: item.isPinned
          ? theme.colorScheme.onInverseSurface.withValues(
              alpha: theme.isDark ? 0.4 : 0.8,
            )
          : null,
      onLongPress: () => showDialog(
        context: context,
        builder: (context) => DefaultTextStyle(
          style: const TextStyle(fontSize: 14),
          child: SimpleDialog(
            clipBehavior: Clip.hardEdge,
            contentPadding: const EdgeInsets.symmetric(vertical: 12),
            children: [
              SimpleDialogOption(
                onPressed: () {
                  Get.back();
                  onSetTop(item.isPinned, item.id);
                },
                child: Text(item.isPinned ? '移除置顶' : '置顶'),
              ),
              if (item.id.privateId.hasTalkerUid())
                SimpleDialogOption(
                  onPressed: () {
                    Get.back();
                    onSetMute(item.isMuted, item.id.privateId.talkerUid);
                  },
                  child: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
                ),
              if (item.id.privateId.hasTalkerUid())
                SimpleDialogOption(
                  onPressed: () {
                    Get.back();
                    showConfirmDialog(
                      context: context,
                      title: const Text('确定删除该对话？'),
                      onConfirm: () =>
                          onRemove(item.id.privateId.talkerUid.toInt()),
                    );
                  },
                  child: const Text('删除'),
                ),
            ],
          ),
        ),
      ),
      onSecondaryTapUp: PlatformUtils.isDesktop
          ? (details) => showMenu(
              context: context,
              position: PageUtils.menuPosition(details.globalPosition),
              items: [
                PopupMenuItem(
                  height: 42,
                  onTap: () => onSetTop(item.isPinned, item.id),
                  child: Text(item.isPinned ? '移除置顶' : '置顶'),
                ),
                if (item.id.privateId.hasTalkerUid())
                  PopupMenuItem(
                    height: 42,
                    onTap: () =>
                        onSetMute(item.isMuted, item.id.privateId.talkerUid),
                    child: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
                  ),
                if (item.id.privateId.hasTalkerUid())
                  PopupMenuItem(
                    height: 42,
                    onTap: () => showConfirmDialog(
                      context: context,
                      title: const Text('确定删除该对话？'),
                      onConfirm: () =>
                          onRemove(item.id.privateId.talkerUid.toInt()),
                    ),
                    child: const Text('删除'),
                  ),
              ],
            )
          : null,
      onTap: () {
        if (item.hasUnread()) {
          item.clearUnread();
          if (context.mounted) {
            (context as Element).markNeedsBuild();
          }
        }
        if (item.id.privateId.hasTalkerUid()) {
          Get.toNamed(
            '/whisperDetail',
            arguments: {
              'talkerId': item.id.privateId.talkerUid.toInt(),
              'name': item.sessionInfo.sessionName,
              'face': avatar,
              if (item.sessionInfo.avatar.hasMid())
                'mid': item.sessionInfo.avatar.mid.toInt(),
              'isLive': item.sessionInfo.isLive,
            },
          );
          return;
        }

        if (item.id.foldId.hasType()) {
          SessionPageType? sessionPageType = switch (item.id.foldId.type) {
            SessionType.SESSION_TYPE_UNKNOWN =>
              SessionPageType.SESSION_PAGE_TYPE_UNKNOWN,
            SessionType.SESSION_TYPE_GROUP =>
              SessionPageType.SESSION_PAGE_TYPE_GROUP,
            SessionType.SESSION_TYPE_GROUP_FOLD =>
              SessionPageType.SESSION_PAGE_TYPE_GROUP,
            SessionType.SESSION_TYPE_UNFOLLOWED =>
              SessionPageType.SESSION_PAGE_TYPE_UNFOLLOWED,
            SessionType.SESSION_TYPE_STRANGER =>
              SessionPageType.SESSION_PAGE_TYPE_STRANGER,
            SessionType.SESSION_TYPE_DUSTBIN =>
              SessionPageType.SESSION_PAGE_TYPE_DUSTBIN,
            SessionType.SESSION_TYPE_CUSTOMER_FOLD =>
              SessionPageType.SESSION_PAGE_TYPE_CUSTOMER,
            SessionType.SESSION_TYPE_AI_FOLD =>
              SessionPageType.SESSION_PAGE_TYPE_AI,
            SessionType.SESSION_TYPE_CUSTOMER_ACCOUNT =>
              SessionPageType.SESSION_PAGE_TYPE_CUSTOMER,
            _ => null,
          };
          if (sessionPageType != null) {
            Get.to(
              WhisperSecPage(
                name: item.sessionInfo.sessionName,
                sessionPageType: sessionPageType,
              ),
            );
          } else {
            SmartDialog.showToast(item.id.foldId.type.name);
          }
          return;
        }

        if (item.id.hasSystemId()) {
          switch (item.id.systemId.type) {
            case SessionType.SESSION_TYPE_SYSTEM:
              Get.toNamed('/sysMsg');
            case SessionType.SESSION_TYPE_AI_FOLD:
            case SessionType.SESSION_TYPE_CUSTOMER_ACCOUNT:
            case SessionType.SESSION_TYPE_CUSTOMER_FOLD:
            case SessionType.SESSION_TYPE_DUSTBIN:
            case SessionType.SESSION_TYPE_GROUP:
            case SessionType.SESSION_TYPE_GROUP_FOLD:
            case SessionType.SESSION_TYPE_PRIVATE:
            case SessionType.SESSION_TYPE_STRANGER:
            case SessionType.SESSION_TYPE_UNFOLLOWED:
            case SessionType.SESSION_TYPE_UNKNOWN:
              SmartDialog.showToast(item.id.systemId.type.name);
          }
        }
      },
      leading: Builder(
        builder: (context) {
          final pendant = item.sessionInfo.avatar.fallbackLayers.layers
              .elementAtOrNull(1)
              ?.resource;
          final official = item
              .sessionInfo
              .avatar
              .fallbackLayers
              .layers
              .lastOrNull
              ?.resource
              .resImage
              .imageSrc;

          return GestureDetector(
            onTap: item.sessionInfo.avatar.hasMid()
                ? () =>
                      Get.toNamed('/member?mid=${item.sessionInfo.avatar.mid}')
                : null,
            child: PendantAvatar(
              avatar,
              size: 42,
              badgeSize: 14,
              pendantImage: pendant?.resImage.imageSrc.remote.hasUrl() == true
                  ? pendant!.resImage.imageSrc.remote.url
                  : pendant?.resAnimation.webpSrc.remote.url,
              vipStatus: vipInfo?['status'],
              officialType: official?.hasLocalValue() == true
                  ? switch (official!.localValue) {
                      3 => 0,
                      4 => 1,
                      _ => null,
                    }
                  : null,
            ),
          );
        },
      ),
      title: Row(
        spacing: 5,
        children: [
          Expanded(
            child: Row(
              spacing: 5,
              children: [
                Flexible(
                  child: Text(
                    item.sessionInfo.sessionName,
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                      fontSize: 15,
                      color:
                          vipInfo?['status'] != null &&
                              vipInfo!['status'] > 0 &&
                              vipInfo['type'] == 2
                          ? theme.colorScheme.vipColor
                          : null,
                    ),
                  ),
                ),
                if (item.sessionInfo.userLabel.style.borderedLabel.hasText())
                  PBadge(
                    isStack: false,
                    type: PBadgeType.line_secondary,
                    size: PBadgeSize.small,
                    fontSize: 10,
                    isBold: false,
                    text: item.sessionInfo.userLabel.style.borderedLabel.text,
                  ),
                if (item.sessionInfo.isLive)
                  Image.asset(
                    Assets.livingRect,
                    height: 15,
                    cacheHeight: 15.cacheSize(context),
                    filterQuality: FilterQuality.low,
                  ),
              ],
            ),
          ),
          if (item.hasTimestamp())
            Text(
              DateFormatUtils.dateFormat((item.timestamp ~/ 1000000).toInt()),
              style: TextStyle(
                fontSize: 12,
                color: theme.colorScheme.outline,
              ),
            ),
        ],
      ),
      subtitle: Row(
        children: [
          Expanded(
            child: Text(
              item.msgSummary.rawMsg,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: theme.textTheme.labelMedium!.copyWith(
                color: theme.colorScheme.outline,
              ),
            ),
          ),
          if (item.isMuted)
            Icon(
              size: 16,
              Icons.notifications_off,
              color: theme.colorScheme.outline,
            )
          else if (item.hasUnread() &&
              item.unread.style != UnreadStyle.UNREAD_STYLE_NONE)
            Badge(
              label: item.unread.style == UnreadStyle.UNREAD_STYLE_NUMBER
                  ? Text(item.unread.number.toString())
                  : null,
            ),
        ],
      ),
    );
  }
}
