import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flushbar/flushbar_helper.dart';
import 'package:circular_check_box/circular_check_box.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/matrix_locals.dart';
import 'package:fluffychat/views/chat.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:pedantic/pedantic.dart';

import '../../utils/app_route.dart';
import '../../utils/date_time_extension.dart';
import '../../views/chat.dart';
import '../avatar.dart';
import '../dialogs/send_file_dialog.dart';
import '../dialogs/simple_dialogs.dart';
import '../matrix.dart';
import '../mouse_over_builder.dart';
import '../theme_switcher.dart';

enum ArchivedRoomAction { delete, rejoin }

class ChatListItem extends StatelessWidget {
  final Room room;
  final bool activeChat;
  final bool selected;
  final Function onForget;
  final Function onTap;
  final Function onLongPress;

  const ChatListItem(this.room,
      {this.activeChat = false,
      this.selected = false,
      this.onTap,
      this.onLongPress,
      this.onForget});

  void clickAction(BuildContext context) async {
    if (onTap != null) return onTap();
    if (!activeChat) {
      if (room.membership == Membership.invite &&
          await SimpleDialogs(context)
                  .tryRequestWithLoadingDialog(room.join()) ==
              false) {
        return;
      }

      if (room.membership == Membership.ban) {
        await FlushbarHelper.createError(
                message: L10n.of(context).youHaveBeenBannedFromThisChat)
            .show(context);
        return;
      }

      if (room.membership == Membership.leave) {
        final action = await showModalActionSheet<ArchivedRoomAction>(
          context: context,
          title: L10n.of(context).archivedRoom,
          message: L10n.of(context).thisRoomHasBeenArchived,
          actions: [
            SheetAction(
              label: L10n.of(context).rejoin,
              key: ArchivedRoomAction.rejoin,
            ),
            SheetAction(
              label: L10n.of(context).delete,
              key: ArchivedRoomAction.delete,
              isDestructiveAction: true,
            ),
          ],
        );
        if (action != null) {
          switch (action) {
            case ArchivedRoomAction.delete:
              await archiveAction(context);
              break;
            case ArchivedRoomAction.rejoin:
              await SimpleDialogs(context)
                  .tryRequestWithLoadingDialog(room.join());
              break;
          }
        }
      }

      if (room.membership == Membership.join) {
        if (Matrix.of(context).shareContent != null) {
          if (Matrix.of(context).shareContent['msgtype'] ==
              'chat.fluffy.shared_file') {
            await showDialog(
                context: context,
                builder: (context) => SendFileDialog(
                      file: Matrix.of(context).shareContent['file'],
                      room: room,
                    ));
          } else {
            unawaited(room.sendEvent(Matrix.of(context).shareContent));
          }
          Matrix.of(context).shareContent = null;
        }
        await Navigator.pushAndRemoveUntil(
          context,
          AppRoute.defaultRoute(context, ChatView(room.id)),
          (r) => r.isFirst,
        );
      }
    }
  }

  Future<void> archiveAction(BuildContext context) async {
    {
      if ([Membership.leave, Membership.ban].contains(room.membership)) {
        final success = await SimpleDialogs(context)
            .tryRequestWithLoadingDialog(room.forget());
        if (success != false) {
          if (onForget != null) onForget();
        }
        return success;
      }
      final confirmed = await showOkCancelAlertDialog(
        context: context,
        title: L10n.of(context).areYouSure,
      );
      if (confirmed == OkCancelResult.cancel) return;
      await SimpleDialogs(context).tryRequestWithLoadingDialog(room.leave());
      return;
    }
  }

  @override
  Widget build(BuildContext context) {
    final isMuted = room.pushRuleState != PushRuleState.notify;
    return Center(
      child: Material(
        color: chatListItemColor(context, activeChat, selected),
        child: ListTile(
          onLongPress: onLongPress,
          leading: MouseOverBuilder(
            builder: (context, hover) =>
                onLongPress != null && (hover || selected)
                    ? Container(
                        width: Avatar.defaultSize,
                        height: Avatar.defaultSize,
                        alignment: Alignment.center,
                        child: CircularCheckBox(
                          value: selected,
                          onChanged: (_) => onLongPress(),
                        ),
                      )
                    : Avatar(room.avatar, room.displayname),
          ),
          title: Row(
            children: <Widget>[
              Expanded(
                child: Text(
                  room.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  softWrap: false,
                ),
              ),
              room.isFavourite
                  ? Padding(
                      padding: const EdgeInsets.only(left: 4.0),
                      child: Icon(
                        Icons.favorite_outline_rounded,
                        size: 16,
                      ),
                    )
                  : Container(),
              isMuted
                  ? Padding(
                      padding: const EdgeInsets.only(left: 4.0),
                      child: Icon(
                        Icons.notifications_off_outlined,
                        size: 16,
                      ),
                    )
                  : Container(),
              Padding(
                padding: const EdgeInsets.only(left: 4.0),
                child: Text(
                  room.timeCreated.localizedTimeShort(context),
                  style: TextStyle(
                    fontSize: 13,
                  ),
                ),
              ),
            ],
          ),
          subtitle: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                child: room.membership == Membership.invite
                    ? Text(
                        L10n.of(context).youAreInvitedToThisChat,
                        style: TextStyle(
                          color: Theme.of(context).primaryColor,
                        ),
                        softWrap: false,
                      )
                    : Text(
                        room.lastEvent?.getLocalizedBody(
                              MatrixLocals(L10n.of(context)),
                              withSenderNamePrefix: !room.isDirectChat ||
                                  room.lastEvent.senderId == room.client.userID,
                              hideReply: true,
                            ) ??
                            '',
                        softWrap: false,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: TextStyle(
                          decoration: room.lastEvent?.redacted == true
                              ? TextDecoration.lineThrough
                              : null,
                        ),
                      ),
              ),
              SizedBox(width: 8),
              room.notificationCount > 0
                  ? Container(
                      padding: EdgeInsets.symmetric(horizontal: 5),
                      height: 20,
                      decoration: BoxDecoration(
                        color: room.highlightCount > 0
                            ? Colors.red
                            : Theme.of(context).primaryColor,
                        borderRadius: BorderRadius.circular(20),
                      ),
                      child: Center(
                        child: Text(
                          room.notificationCount.toString(),
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    )
                  : Text(' '),
            ],
          ),
          onTap: () => clickAction(context),
        ),
      ),
    );
  }
}