import 'dart:async';
import 'dart:io' show File;

import 'package:PiliPlus/common/assets.dart';
import 'package:PiliPlus/common/widgets/dialog/report.dart';
import 'package:PiliPlus/common/widgets/flutter/chat_list_view.dart';
import 'package:PiliPlus/common/widgets/flutter/text_field/text_field.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg;
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/msg.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/common/publish_panel_type.dart';
import 'package:PiliPlus/pages/common/publish/common_rich_text_pub_page.dart';
import 'package:PiliPlus/pages/emote/view.dart';
import 'package:PiliPlus/pages/whisper_detail/controller.dart';
import 'package:PiliPlus/pages/whisper_detail/widget/chat_item.dart';
import 'package:PiliPlus/pages/whisper_link_setting/view.dart';
import 'package:PiliPlus/utils/extension/file_ext.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/extension/widget_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide TextField;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mime/mime.dart';

class WhisperDetailPage extends CommonRichTextPubPage {
  const WhisperDetailPage({
    super.key,
    super.autofocus = false,
  });

  @override
  State<WhisperDetailPage> createState() => _WhisperDetailPageState();
}

class _WhisperDetailPageState
    extends CommonRichTextPubPageState<WhisperDetailPage> {
  final _whisperDetailController = Get.put(
    WhisperDetailController(),
    tag: Utils.makeHeroTag(Get.parameters['talkerId']),
  );

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final padding = MediaQuery.viewPaddingOf(context);
    late final containerColor = ElevationOverlay.colorWithOverlay(
      theme.colorScheme.surface,
      theme.hoverColor,
      1,
    );
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(
        title: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: () {
            if (_whisperDetailController.mid != null) {
              feedBack();
              Get.toNamed('/member?mid=${_whisperDetailController.mid}');
            }
          },
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              NetworkImgLayer(
                width: 34,
                height: 34,
                type: ImageType.avatar,
                src: _whisperDetailController.face,
              ),
              const SizedBox(width: 6),
              Flexible(
                child: Text(
                  _whisperDetailController.name,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: const TextStyle(height: 1, fontSize: 16),
                  strutStyle: const StrutStyle(
                    leading: 0,
                    height: 1,
                    fontSize: 16,
                  ),
                ),
              ),
              if (_whisperDetailController.isLive) ...[
                const SizedBox(width: 10),
                Image.asset(
                  Assets.livingRect,
                  height: 16,
                  cacheHeight: 16.cacheSize(context),
                  filterQuality: FilterQuality.low,
                ),
              ],
            ],
          ),
        ),
        actions: [
          IconButton(
            tooltip: '设置',
            onPressed: () => Get.to(
              WhisperLinkSettingPage(
                talkerUid: _whisperDetailController.talkerId,
              ),
            ),
            icon: Icon(
              size: 22,
              Icons.settings,
              color: theme.colorScheme.onSurfaceVariant.withValues(alpha: 0.8),
            ),
          ),
          const SizedBox(width: 5),
        ],
      ),
      body: Padding(
        padding: EdgeInsets.only(left: padding.left, right: padding.right),
        child: Column(
          children: [
            Expanded(
              child: Listener(
                onPointerDown: hidePanel,
                behavior: HitTestBehavior.opaque,
                child: Align(
                  alignment: Alignment.topCenter,
                  child: Obx(
                    () =>
                        _buildBody(_whisperDetailController.loadingState.value),
                  ),
                ),
              ),
            ),
            if (_whisperDetailController.mid != null) ...[
              _buildInputView(theme, containerColor),
              buildPanelContainer(
                theme,
                containerColor,
              ),
            ] else
              SizedBox(height: padding.bottom),
          ],
        ),
      ).constraintWidth(),
    );
  }

  Widget _buildBody(LoadingState<List<Msg>?> loadingState) {
    return switch (loadingState) {
      Loading() => m3eLoading,
      Success(:final response) =>
        response != null && response.isNotEmpty
            ? ChatListView.separated(
                itemCount: response.length,
                padding: const .all(kChatListPadding),
                physics: const AlwaysScrollableScrollPhysics(
                  parent: ClampingScrollPhysics(),
                ),
                controller: _whisperDetailController.scrollController,
                itemBuilder: (context, int index) {
                  if (index == response.length - 1) {
                    _whisperDetailController.onLoadMore();
                  }
                  final item = response[index];
                  final isOwner =
                      item.senderUid.toInt() ==
                      _whisperDetailController.account.mid;
                  return ChatItem(
                    item: item,
                    eInfos: _whisperDetailController.eInfos,
                    onLongPress: () => onLongPress(index, item, isOwner),
                    onSecondaryTapUp: PlatformUtils.isDesktop
                        ? (e) =>
                              _showMenu(e.globalPosition, index, item, isOwner)
                        : null,
                    isOwner: isOwner,
                  );
                },
                separatorBuilder: (context, index) =>
                    const SizedBox(height: 12),
              )
            : scrollErrorWidget(onReload: _whisperDetailController.onReload),
      Error(:final errMsg) => scrollErrorWidget(
        errMsg: errMsg,
        onReload: _whisperDetailController.onReload,
      ),
    };
  }

  void _showMenu(Offset offset, int index, Msg item, bool isOwner) {
    showMenu(
      context: context,
      position: PageUtils.menuPosition(offset),
      items: [
        if (isOwner)
          PopupMenuItem(
            height: 42,
            onTap: () => _whisperDetailController.sendMsg(
              message: '${item.msgKey}',
              onClearText: editController.clear,
              msgType: 5,
              index: index,
            ),
            child: const Text('撤回', style: TextStyle(fontSize: 14)),
          )
        else
          PopupMenuItem(
            height: 42,
            onTap: () => autoWrapReportDialog(
              context,
              ban: false,
              ReportOptions.imMsgReport,
              (reasonType, reasonDesc, banUid) =>
                  _whisperDetailController.onReport(
                    item,
                    reasonType,
                    reasonType == 0
                        ? reasonDesc!
                        : ReportOptions.imMsgReport['']![reasonType]!,
                  ),
            ),
            child: const Text('举报', style: TextStyle(fontSize: 14)),
          ),
      ],
    );
  }

  void onLongPress(int index, Msg item, bool isOwner) {
    Feedback.forLongPress(context);
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        clipBehavior: Clip.hardEdge,
        contentPadding: const EdgeInsets.symmetric(vertical: 12),
        content: isOwner
            ? ListTile(
                onTap: () {
                  Get.back();
                  _whisperDetailController.sendMsg(
                    message: '${item.msgKey}',
                    onClearText: editController.clear,
                    msgType: 5,
                    index: index,
                  );
                },
                dense: true,
                title: const Text('撤回', style: TextStyle(fontSize: 14)),
              )
            : ListTile(
                onTap: () {
                  Get.back();
                  autoWrapReportDialog(
                    context,
                    ban: false,
                    ReportOptions.imMsgReport,
                    (reasonType, reasonDesc, banUid) =>
                        _whisperDetailController.onReport(
                          item,
                          reasonType,
                          reasonType == 0
                              ? reasonDesc!
                              : ReportOptions.imMsgReport['']![reasonType]!,
                        ),
                  );
                },
                dense: true,
                title: const Text('举报', style: TextStyle(fontSize: 14)),
              ),
      ),
    );
  }

  Widget _buildInputView(ThemeData theme, Color containerColor) {
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 8),
      decoration: BoxDecoration(
        color: containerColor,
        borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          IconButton(
            onPressed: () => updatePanelType(
              panelType.value == PanelType.emoji
                  ? PanelType.keyboard
                  : PanelType.emoji,
            ),
            icon: const Icon(Icons.emoji_emotions),
            tooltip: '表情',
          ),
          Expanded(
            child: Listener(
              onPointerUp: (event) {
                // Currently it may be emojiPanel.
                if (readOnly.value) {
                  updatePanelType(PanelType.keyboard);
                }
              },
              child: Obx(
                () => RichTextField(
                  key: key,
                  readOnly: readOnly.value,
                  focusNode: focusNode,
                  controller: editController,
                  minLines: 1,
                  maxLines: 4,
                  onChanged: onChanged,
                  onSubmitted: onSubmitted,
                  textInputAction: TextInputAction.newline,
                  decoration: InputDecoration(
                    filled: true,
                    hintText: '发个消息聊聊呗~',
                    fillColor: theme.colorScheme.surface,
                    border: const OutlineInputBorder(
                      borderSide: BorderSide.none,
                      borderRadius: BorderRadius.all(Radius.circular(6)),
                      gapPadding: 0,
                    ),
                    contentPadding: const EdgeInsets.all(10),
                  ),
                  // inputFormatters: [LengthLimitingTextInputFormatter(500)],
                ),
              ),
            ),
          ),
          Obx(
            () {
              final enablePublish = this.enablePublish.value;
              return IconButton(
                onPressed: () async {
                  if (enablePublish) {
                    _whisperDetailController.sendMsg(
                      message: editController.rawText,
                      onClearText: () {
                        editController.clear();
                        this.enablePublish.value = false;
                      },
                    );
                  } else {
                    try {
                      final pickedFile = await imagePicker.pickImage(
                        source: ImageSource.gallery,
                        imageQuality: 100,
                        requestFullMetadata: false,
                      );
                      if (pickedFile != null) {
                        final path = pickedFile.path;
                        SmartDialog.showLoading(msg: '正在上传图片');
                        final result = await MsgHttp.uploadBfs(
                          path: path,
                          biz: 'im',
                        );
                        if (result case Success(:final response)) {
                          final mimeType =
                              lookupMimeType(
                                path,
                              )?.split('/').elementAtOrNull(1) ??
                              'jpg';
                          final picMsg = {
                            'url': response.imageUrl,
                            'height': response.imageHeight,
                            'width': response.imageWidth,
                            'imageType': mimeType,
                            'original': 1,
                            'size': response.imgSize,
                          };
                          SmartDialog.showLoading(msg: '正在发送');
                          await _whisperDetailController
                              .sendMsg(
                                picMsg: picMsg,
                                onClearText: editController.clear,
                              )
                              .whenComplete(() {
                                if (PlatformUtils.isMobile) {
                                  File(path).tryDel();
                                }
                              });
                        } else {
                          SmartDialog.dismiss();
                          result.toast();
                          return;
                        }
                      }
                    } catch (e) {
                      SmartDialog.showToast(e.toString());
                    }
                  }
                },
                icon: Icon(
                  enablePublish
                      ? Icons.send
                      : Icons.add_photo_alternate_outlined,
                ),
                tooltip: enablePublish ? '发送' : '图片',
              );
            },
          ),
        ],
      ),
    );
  }

  @override
  Widget? get customPanel => EmotePanel(onChoose: onChooseEmote);

  @override
  Future<void> onCustomPublish({List? pictures}) {
    throw UnimplementedError();
  }

  @override
  Future<void>? onMention([bool fromClick = false]) => null;

  @override
  void onSave() {}
}
