import 'package:flutter/material.dart';

import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:matrix/matrix.dart';
import 'package:vrouter/vrouter.dart';

import 'package:fluffychat/utils/matrix_sdk_extensions.dart/client_stories_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';

enum ContextualRoomAction {
  mute,
  unmute,
  leave,
}

class StoriesHeader extends StatelessWidget {
  const StoriesHeader({Key? key}) : super(key: key);

  void _addToStoryAction(BuildContext context) =>
      VRouter.of(context).to('/stories/create');

  void _goToStoryAction(BuildContext context, String roomId) async {
    final room = Matrix.of(context).client.getRoomById(roomId);
    if (room == null) return;
    if (room.membership != Membership.join) {
      final result = await showFutureLoadingDialog(
        context: context,
        future: room.join,
      );
      if (result.error != null) return;
    }
    VRouter.of(context).toSegments(['stories', roomId]);
  }

  void _contextualActions(BuildContext context, Room room) async {
    final action = await showModalActionSheet<ContextualRoomAction>(
      cancelLabel: L10n.of(context)!.cancel,
      context: context,
      actions: [
        if (room.pushRuleState != PushRuleState.notify)
          SheetAction(
            label: L10n.of(context)!.unmuteChat,
            key: ContextualRoomAction.unmute,
            icon: Icons.notifications_outlined,
          )
        else
          SheetAction(
            label: L10n.of(context)!.muteChat,
            key: ContextualRoomAction.mute,
            icon: Icons.notifications_off_outlined,
          ),
        SheetAction(
          label: L10n.of(context)!.unsubscribeStories,
          key: ContextualRoomAction.leave,
          icon: Icons.unsubscribe_outlined,
          isDestructiveAction: true,
        ),
      ],
    );
    if (action == null) return;
    switch (action) {
      case ContextualRoomAction.mute:
        await showFutureLoadingDialog(
          context: context,
          future: () => room.setPushRuleState(PushRuleState.dontNotify),
        );
        break;
      case ContextualRoomAction.unmute:
        await showFutureLoadingDialog(
          context: context,
          future: () => room.setPushRuleState(PushRuleState.notify),
        );
        break;
      case ContextualRoomAction.leave:
        await showFutureLoadingDialog(
          context: context,
          future: () => room.leave(),
        );
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    final client = Matrix.of(context).client;
    return StreamBuilder(
      stream: Matrix.of(context).onShareContentChanged.stream,
      builder: (context, _) => StreamBuilder<Object>(
          stream: client.onSync.stream
              .where((syncUpdate) => syncUpdate.hasRoomUpdate),
          builder: (context, snapshot) {
            if (Matrix.of(context).shareContent != null) {
              return ListTile(
                leading: CircleAvatar(
                  radius: Avatar.defaultSize / 2,
                  backgroundColor: Theme.of(context).colorScheme.surface,
                  foregroundColor: Theme.of(context).textTheme.bodyText1?.color,
                  child: const Icon(Icons.camera_alt_outlined),
                ),
                title: Text(L10n.of(context)!.addToStory),
                onTap: () => _addToStoryAction(context),
              );
            }
            if (client.storiesRooms.isEmpty) {
              return Container();
            }
            return SizedBox(
              height: 106,
              child: ListView(
                padding: const EdgeInsets.symmetric(horizontal: 2),
                scrollDirection: Axis.horizontal,
                children: [
                  _StoryButton(
                    label: L10n.of(context)!.yourStory,
                    onPressed: () => _addToStoryAction(context),
                    child: const Icon(Icons.camera_alt_outlined),
                  ),
                  ...client.storiesRooms.map(
                    (room) => Opacity(
                      opacity: room.hasPosts ? 1 : 0.75,
                      child: FutureBuilder<Profile>(
                          future: room.getCreatorProfile(),
                          builder: (context, snapshot) {
                            final displayname = snapshot.data?.displayName ??
                                room
                                    .getState(EventTypes.RoomCreate)!
                                    .senderId
                                    .localpart!;
                            final avatarUrl = snapshot.data?.avatarUrl;
                            return _StoryButton(
                              label: displayname,
                              child: Avatar(
                                mxContent: avatarUrl,
                                name: displayname,
                                size: 100,
                                fontSize: 24,
                              ),
                              unread: room.membership == Membership.invite ||
                                  room.hasNewMessages,
                              onPressed: () =>
                                  _goToStoryAction(context, room.id),
                              onLongPressed: () =>
                                  _contextualActions(context, room),
                            );
                          }),
                    ),
                  ),
                ],
              ),
            );
          }),
    );
  }
}

extension on Room {
  Future<Profile> getCreatorProfile() =>
      client.getProfileFromUserId(getState(EventTypes.RoomCreate)!.senderId);

  bool get hasPosts {
    if (membership == Membership.invite) return true;
    final lastEvent = this.lastEvent;
    if (lastEvent == null) return false;
    if (lastEvent.type != EventTypes.Message) return false;
    if (DateTime.now().difference(lastEvent.originServerTs).inHours >
        ClientStoriesExtension.lifeTimeInHours) {
      return false;
    }
    return true;
  }
}

class _StoryButton extends StatelessWidget {
  final Widget child;
  final String label;
  final void Function() onPressed;
  final void Function()? onLongPressed;
  final bool unread;

  const _StoryButton({
    required this.child,
    required this.label,
    required this.onPressed,
    this.unread = false,
    this.onLongPressed,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 78,
      child: InkWell(
        borderRadius: BorderRadius.circular(7),
        onTap: onPressed,
        onLongPress: onLongPressed,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 4),
          child: Column(
            children: [
              const SizedBox(height: 8),
              Material(
                elevation: Theme.of(context).appBarTheme.elevation ?? 7,
                shadowColor: Theme.of(context).appBarTheme.shadowColor,
                borderRadius: BorderRadius.circular(Avatar.defaultSize),
                child: Container(
                  padding: const EdgeInsets.all(2),
                  decoration: BoxDecoration(
                    gradient: unread
                        ? const LinearGradient(
                            colors: [
                              Colors.red,
                              Colors.purple,
                              Colors.orange,
                            ],
                            begin: Alignment.topLeft,
                            end: Alignment.bottomRight,
                          )
                        : null,
                    color: unread ? null : Theme.of(context).dividerColor,
                    borderRadius: BorderRadius.circular(Avatar.defaultSize),
                  ),
                  child: Material(
                    color: Theme.of(context).colorScheme.surface,
                    borderRadius: BorderRadius.circular(Avatar.defaultSize),
                    child: Padding(
                      padding: const EdgeInsets.all(2.0),
                      child: CircleAvatar(
                        radius: 30,
                        backgroundColor: Theme.of(context).colorScheme.surface,
                        foregroundColor:
                            Theme.of(context).textTheme.bodyText1?.color,
                        child: child,
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(height: 8),
              Text(
                label,
                maxLines: 1,
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 12,
                  fontWeight: unread ? FontWeight.bold : null,
                ),
              ),
              const SizedBox(height: 8),
            ],
          ),
        ),
      ),
    );
  }
}