import 'package:flutter/material.dart';

import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';

import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/presence_builder.dart';
import '../../widgets/matrix.dart';
import 'user_bottom_sheet.dart';

class UserBottomSheetView extends StatelessWidget {
  final UserBottomSheetController controller;

  const UserBottomSheetView(this.controller, {super.key});

  @override
  Widget build(BuildContext context) {
    final user = controller.widget.user;
    final userId = (user?.id ?? controller.widget.profile?.userId)!;
    final displayname = (user?.calcDisplayname() ??
        controller.widget.profile?.displayName ??
        controller.widget.profile?.userId.localpart)!;
    final avatarUrl = user?.avatarUrl ?? controller.widget.profile?.avatarUrl;

    final client = Matrix.of(controller.widget.outerContext).client;
    final profileSearchError = controller.widget.profileSearchError;
    final dmRoomId = client.getDirectChatFromUserId(userId);
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          leading: CloseButton(
            onPressed: Navigator.of(context, rootNavigator: false).pop,
          ),
          centerTitle: false,
          title: Text(displayname),
          actions: dmRoomId == null
              ? null
              : [
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 8),
                    child: FloatingActionButton.small(
                      elevation: 0,
                      onPressed: () => controller
                          .participantAction(UserBottomSheetAction.message),
                      child: const Icon(Icons.chat_outlined),
                    ),
                  ),
                ],
        ),
        body: StreamBuilder<Object>(
          stream: user?.room.client.onSync.stream.where(
            (syncUpdate) =>
                syncUpdate.rooms?.join?[user.room.id]?.timeline?.events?.any(
                  (state) => state.type == EventTypes.RoomPowerLevels,
                ) ??
                false,
          ),
          builder: (context, snapshot) {
            final theme = Theme.of(context);
            return ListView(
              children: [
                if (user?.membership == Membership.knock)
                  Padding(
                    padding: const EdgeInsets.all(12.0),
                    child: Material(
                      color:
                          // ignore: deprecated_member_use
                          theme.colorScheme.surfaceVariant,
                      borderRadius:
                          BorderRadius.circular(AppConfig.borderRadius),
                      child: ListTile(
                        minVerticalPadding: 16,
                        title: Padding(
                          padding: const EdgeInsets.only(bottom: 12.0),
                          child: Text(
                            L10n.of(context)!
                                .userWouldLikeToChangeTheChat(displayname),
                          ),
                        ),
                        subtitle: Row(
                          children: [
                            TextButton.icon(
                              style: TextButton.styleFrom(
                                backgroundColor: theme.colorScheme.surface,
                                foregroundColor: theme.colorScheme.primary,
                              ),
                              onPressed: controller.knockAccept,
                              icon: const Icon(Icons.check_outlined),
                              label: Text(L10n.of(context)!.accept),
                            ),
                            const SizedBox(width: 12),
                            TextButton.icon(
                              style: TextButton.styleFrom(
                                backgroundColor:
                                    theme.colorScheme.errorContainer,
                                foregroundColor:
                                    theme.colorScheme.onErrorContainer,
                              ),
                              onPressed: controller.knockDecline,
                              icon: const Icon(Icons.cancel_outlined),
                              label: Text(L10n.of(context)!.decline),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                Row(
                  children: [
                    Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Avatar(
                        client:
                            Matrix.of(controller.widget.outerContext).client,
                        mxContent: avatarUrl,
                        name: displayname,
                        size: Avatar.defaultSize * 2.5,
                      ),
                    ),
                    Expanded(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          TextButton.icon(
                            onPressed: () => FluffyShare.share(
                              userId,
                              context,
                              copyOnly: true,
                            ),
                            icon: const Icon(
                              Icons.copy_outlined,
                              size: 14,
                            ),
                            style: TextButton.styleFrom(
                              foregroundColor: theme.colorScheme.onSurface,
                            ),
                            label: Text(
                              userId,
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                          PresenceBuilder(
                            userId: userId,
                            client: client,
                            builder: (context, presence) {
                              if (presence == null ||
                                  (presence.presence == PresenceType.offline &&
                                      presence.lastActiveTimestamp == null)) {
                                return const SizedBox.shrink();
                              }

                              final dotColor = presence.presence.isOnline
                                  ? Colors.green
                                  : presence.presence.isUnavailable
                                      ? Colors.orange
                                      : Colors.grey;

                              final lastActiveTimestamp =
                                  presence.lastActiveTimestamp;

                              return Row(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  const SizedBox(width: 16),
                                  Container(
                                    width: 8,
                                    height: 8,
                                    decoration: BoxDecoration(
                                      color: dotColor,
                                      borderRadius: BorderRadius.circular(16),
                                    ),
                                  ),
                                  const SizedBox(width: 12),
                                  if (presence.currentlyActive == true)
                                    Text(
                                      L10n.of(context)!.currentlyActive,
                                      overflow: TextOverflow.ellipsis,
                                      style: theme.textTheme.bodySmall,
                                    )
                                  else if (lastActiveTimestamp != null)
                                    Text(
                                      L10n.of(context)!.lastActiveAgo(
                                        lastActiveTimestamp
                                            .localizedTimeShort(context),
                                      ),
                                      overflow: TextOverflow.ellipsis,
                                      style: theme.textTheme.bodySmall,
                                    ),
                                ],
                              );
                            },
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
                PresenceBuilder(
                  userId: userId,
                  client: client,
                  builder: (context, presence) {
                    final status = presence?.statusMsg;
                    if (status == null || status.isEmpty) {
                      return const SizedBox.shrink();
                    }
                    return ListTile(
                      title: SelectableLinkify(
                        text: status,
                        style: const TextStyle(fontSize: 16),
                        options: const LinkifyOptions(humanize: false),
                        linkStyle: const TextStyle(
                          color: Colors.blueAccent,
                          decorationColor: Colors.blueAccent,
                        ),
                        onOpen: (url) =>
                            UrlLauncher(context, url.url).launchUrl(),
                      ),
                    );
                  },
                ),
                if (userId != client.userID)
                  Padding(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 16.0,
                      vertical: 8.0,
                    ),
                    child: dmRoomId == null
                        ? ElevatedButton.icon(
                            onPressed: () => controller.participantAction(
                              UserBottomSheetAction.message,
                            ),
                            icon: const Icon(Icons.chat_outlined),
                            label: Text(L10n.of(context)!.startConversation),
                          )
                        : TextField(
                            controller: controller.sendController,
                            readOnly: controller.isSending,
                            onSubmitted: controller.sendAction,
                            minLines: 1,
                            maxLines: 1,
                            textInputAction: TextInputAction.send,
                            decoration: InputDecoration(
                              errorText: controller.sendError
                                  ?.toLocalizedString(context),
                              hintText: L10n.of(context)!.sendMessages,
                              suffix: controller.isSending
                                  ? const SizedBox(
                                      width: 16,
                                      height: 16,
                                      child: CircularProgressIndicator.adaptive(
                                        strokeWidth: 2,
                                      ),
                                    )
                                  : null,
                              suffixIcon: controller.isSending
                                  ? null
                                  : IconButton(
                                      icon: const Icon(Icons.send_outlined),
                                      onPressed: controller.sendAction,
                                    ),
                            ),
                          ),
                  ),
                if (controller.widget.onMention != null)
                  ListTile(
                    leading: const Icon(Icons.alternate_email_outlined),
                    title: Text(L10n.of(context)!.mention),
                    onTap: () => controller
                        .participantAction(UserBottomSheetAction.mention),
                  ),
                if (user != null) ...[
                  Divider(color: theme.dividerColor),
                  ListTile(
                    title: Text(
                      '${L10n.of(context)!.userRole} (${user.powerLevel})',
                    ),
                    leading: const Icon(Icons.person_outlined),
                    trailing: Material(
                      borderRadius:
                          BorderRadius.circular(AppConfig.borderRadius / 2),
                      color: theme.colorScheme.onInverseSurface,
                      child: DropdownButton<int>(
                        onChanged: user.canChangeUserPowerLevel ||
                                // Workaround until https://github.com/famedly/matrix-dart-sdk/pull/1765
                                (user.room.canChangePowerLevel &&
                                    user.id == user.room.client.userID)
                            ? controller.setPowerLevel
                            : null,
                        value: {0, 50, 100}.contains(user.powerLevel)
                            ? user.powerLevel
                            : null,
                        padding: const EdgeInsets.symmetric(horizontal: 8.0),
                        borderRadius:
                            BorderRadius.circular(AppConfig.borderRadius / 2),
                        underline: const SizedBox.shrink(),
                        items: [
                          DropdownMenuItem(
                            value: 0,
                            child: Text(L10n.of(context)!.user),
                          ),
                          DropdownMenuItem(
                            value: 50,
                            child: Text(L10n.of(context)!.moderator),
                          ),
                          DropdownMenuItem(
                            value: 100,
                            child: Text(L10n.of(context)!.admin),
                          ),
                          DropdownMenuItem(
                            value: null,
                            child: Text(L10n.of(context)!.custom),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
                Divider(color: theme.dividerColor),
                if (user != null && user.canKick)
                  ListTile(
                    textColor: theme.colorScheme.error,
                    iconColor: theme.colorScheme.error,
                    title: Text(L10n.of(context)!.kickFromChat),
                    leading: const Icon(Icons.exit_to_app_outlined),
                    onTap: () => controller
                        .participantAction(UserBottomSheetAction.kick),
                  ),
                if (user != null &&
                    user.canBan &&
                    user.membership != Membership.ban)
                  ListTile(
                    textColor: theme.colorScheme.onErrorContainer,
                    iconColor: theme.colorScheme.onErrorContainer,
                    title: Text(L10n.of(context)!.banFromChat),
                    leading: const Icon(Icons.warning_sharp),
                    onTap: () =>
                        controller.participantAction(UserBottomSheetAction.ban),
                  )
                else if (user != null &&
                    user.canBan &&
                    user.membership == Membership.ban)
                  ListTile(
                    title: Text(L10n.of(context)!.unbanFromChat),
                    leading: const Icon(Icons.warning_outlined),
                    onTap: () => controller
                        .participantAction(UserBottomSheetAction.unban),
                  ),
                if (user != null && user.id != client.userID)
                  ListTile(
                    textColor: theme.colorScheme.onErrorContainer,
                    iconColor: theme.colorScheme.onErrorContainer,
                    title: Text(L10n.of(context)!.reportUser),
                    leading: const Icon(Icons.gavel_outlined),
                    onTap: () => controller
                        .participantAction(UserBottomSheetAction.report),
                  ),
                if (profileSearchError != null)
                  ListTile(
                    leading: const Icon(
                      Icons.warning_outlined,
                      color: Colors.orange,
                    ),
                    subtitle: Text(
                      L10n.of(context)!.profileNotFound,
                      style: const TextStyle(color: Colors.orange),
                    ),
                  ),
                if (userId != client.userID &&
                    !client.ignoredUsers.contains(userId))
                  ListTile(
                    textColor: theme.colorScheme.onErrorContainer,
                    iconColor: theme.colorScheme.onErrorContainer,
                    leading: const Icon(Icons.block_outlined),
                    title: Text(L10n.of(context)!.block),
                    onTap: () => controller
                        .participantAction(UserBottomSheetAction.ignore),
                  ),
              ],
            );
          },
        ),
      ),
    );
  }
}
