part of '../rooms_panel.dart';

enum _SpaceMenuItem {
  newDm, createGroup, createRoom, joinRoom, discoverRooms,
  editSpace, adminSpace, leaveSpace,
}

class _Header extends ConsumerWidget {
  final PyramidTheme pt;
  final String? spaceId;
  const _Header({required this.pt, required this.spaceId});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final isRealSpace = spaceId != null && spaceId != 'dms' && spaceId != 'rooms';
    final size = MediaQuery.sizeOf(context);
    final isMobile = size.width < 900 || size.height < 500;

    final spaces = ref.watch(spacesProvider).valueOrNull ?? [];
    Room? activeSpace;
    if (isRealSpace) {
      try {
        activeSpace = spaces.firstWhere((s) => s.id == spaceId);
      } catch (_) {}
    }
    final client = ref.watch(matrixClientProvider).valueOrNull;
    final isAdmin =
        activeSpace != null && activeSpace.ownPowerLevel >= 50;

    final name = isRealSpace
        ? (activeSpace?.getLocalizedDisplayname() ?? 'Space')
        : (spaceId == 'dms' ? 'Chats' : 'Rooms');

    void handleMenu(_SpaceMenuItem item) {
      switch (item) {
        case _SpaceMenuItem.newDm:
          showDialog(context: context, builder: (_) => const NewDmDialog());
        case _SpaceMenuItem.createGroup:
          showDialog(
              context: context, builder: (_) => const CreateJoinDialog());
        case _SpaceMenuItem.createRoom:
          showDialog(
              context: context, builder: (_) => const CreateJoinDialog());
        case _SpaceMenuItem.joinRoom:
          showDialog(
              context: context,
              builder: (_) =>
                  const CreateJoinDialog(initialTab: CreateJoinTab.join));
        case _SpaceMenuItem.discoverRooms:
          showDialog(
              context: context,
              builder: (_) =>
                  const CreateJoinDialog(initialTab: CreateJoinTab.discover));
        case _SpaceMenuItem.editSpace:
          if (activeSpace != null) {
            showDialog(
                context: context,
                builder: (_) => SpaceEditDialog(space: activeSpace!));
          }
        case _SpaceMenuItem.adminSpace:
          if (activeSpace != null) {
            showDialog(
                context: context,
                builder: (_) => SpaceAdminDialog(space: activeSpace!));
          }
        case _SpaceMenuItem.leaveSpace:
          if (activeSpace != null) {
            final space = activeSpace;
            showDialog<bool>(
              context: context,
              builder: (ctx) => AlertDialog(
                backgroundColor: pt.bg2,
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(pt.rXl),
                    side: BorderSide(color: pt.border)),
                title: Text('Space verlassen?',
                    style: TextStyle(
                        color: pt.fg,
                        fontSize: 16,
                        fontWeight: FontWeight.w700)),
                content: Text(
                    'Du verlässt "${space.getLocalizedDisplayname()}".',
                    style: TextStyle(color: pt.fgMuted, fontSize: 13)),
                actions: [
                  TextButton(
                      onPressed: () => Navigator.pop(ctx, false),
                      child: Text('Abbrechen',
                          style: TextStyle(color: pt.fgMuted))),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                        backgroundColor: pt.danger,
                        foregroundColor: Colors.white,
                        elevation: 0,
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(8))),
                    onPressed: () => Navigator.pop(ctx, true),
                    child: const Text('Verlassen'),
                  ),
                ],
              ),
            ).then((confirmed) {
              if (confirmed == true) {
                space.leave().then((_) {
                  ref.read(activeSpaceIdProvider.notifier).state = 'rooms';
                });
              }
            });
          }
      }
    }

    List<PopupMenuEntry<_SpaceMenuItem>> buildMenuItems() {
      if (spaceId == 'dms' || spaceId == null) {
        return [
          PopupMenuItem(
              value: _SpaceMenuItem.newDm,
              child: _MenuRow(
                  Icons.chat_bubble_outline_rounded, 'Neue Unterhaltung', pt)),
          PopupMenuItem(
              value: _SpaceMenuItem.createGroup,
              child: _MenuRow(Icons.group_add_rounded, 'Gruppe erstellen', pt)),
        ];
      } else if (spaceId == 'rooms') {
        return [
          PopupMenuItem(
              value: _SpaceMenuItem.createRoom,
              child: _MenuRow(Icons.add_rounded, 'Raum erstellen', pt)),
          PopupMenuItem(
              value: _SpaceMenuItem.joinRoom,
              child: _MenuRow(Icons.login_rounded, 'Beitreten', pt)),
          PopupMenuItem(
              value: _SpaceMenuItem.discoverRooms,
              child: _MenuRow(Icons.explore_rounded, 'Entdecken', pt)),
        ];
      } else {
        return [
          if (isAdmin) ...[
            PopupMenuItem(
                value: _SpaceMenuItem.adminSpace,
                child: _MenuRow(
                    Icons.admin_panel_settings_rounded, 'Space verwalten', pt)),
            PopupMenuItem(
                value: _SpaceMenuItem.editSpace,
                child: _MenuRow(Icons.edit_outlined, 'Name/Beschreibung', pt)),
            const PopupMenuDivider(),
          ],
          PopupMenuItem(
              value: _SpaceMenuItem.leaveSpace,
              child: _MenuRow(Icons.exit_to_app_rounded, 'Space verlassen', pt,
                  danger: true)),
        ];
      }
    }

    // Check for banner — space banner for real spaces, server banner otherwise.
    final bannerOverrides = ref.watch(spaceBannerOverrideProvider);
    final serverBanners = ref.watch(serverBannerProvider).valueOrNull ?? {};
    String? bannerUrl;
    if (isRealSpace && activeSpace != null) {
      bannerUrl = bannerOverrides.containsKey(activeSpace.id)
          ? bannerOverrides[activeSpace.id]
          : activeSpace.getState(_kSpaceBannerType)?.content['url'] as String?;
    } else if (client != null) {
      bannerUrl = serverBanners[client.homeserver.toString()];
    }
    final hasBanner = bannerUrl != null && client != null;

    Widget controlsRow = Row(
      children: [
        if (isMobile)
          PyrIconBtn(
            icon: const Icon(Icons.menu_rounded),
            tooltip: 'Spaces',
            onPressed: () => Scaffold.of(context).openDrawer(),
          )
        else ...[
          PyrIconBtn(
            icon: const Icon(Icons.menu_rounded),
            tooltip: 'Toggle sidebar',
            onPressed: () =>
                ref.read(railCollapsedProvider.notifier).update((s) => !s),
          ),
          const SizedBox(width: 4),
        ],
        // Space avatar (only when no banner)
        if (isRealSpace && !hasBanner && client != null && activeSpace != null) ...[
          Container(
            width: 28,
            height: 28,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
              color: pt.accent.withAlpha(40),
            ),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(8),
              child: activeSpace.avatar != null
                  ? MxcAvatar(
                      mxcUri: activeSpace.avatar,
                      client: client,
                      size: 28,
                      borderRadius: BorderRadius.circular(8),
                      placeholder: (_) => Center(
                        child: Text(
                          name.isNotEmpty ? name[0].toUpperCase() : '?',
                          style: TextStyle(
                              color: pt.accent,
                              fontSize: 13,
                              fontWeight: FontWeight.w700),
                        ),
                      ),
                    )
                  : Center(
                      child: Text(
                        name.isNotEmpty ? name[0].toUpperCase() : '?',
                        style: TextStyle(
                            color: pt.accent,
                            fontSize: 13,
                            fontWeight: FontWeight.w700),
                      ),
                    ),
            ),
          ),
          const SizedBox(width: 8),
        ],
        Expanded(
          child: Text(
            name,
            style: TextStyle(
              color: hasBanner ? Colors.white : pt.fg,
              fontSize: 15,
              fontWeight: isRealSpace ? FontWeight.w700 : FontWeight.w600,
              shadows: hasBanner
                  ? [const Shadow(blurRadius: 4, color: Colors.black45)]
                  : null,
            ),
            overflow: TextOverflow.ellipsis,
          ),
        ),
        if (isRealSpace && isAdmin)
          PyrIconBtn(
            icon: Icon(Icons.admin_panel_settings_rounded,
                color: hasBanner ? Colors.white70 : null),
            tooltip: 'Space verwalten',
            onPressed: () => handleMenu(_SpaceMenuItem.adminSpace),
          ),
        if (!isRealSpace)
          _NotificationsButton(pt: pt, hasBanner: hasBanner),
        PopupMenuButton<_SpaceMenuItem>(
          tooltip: 'Erstellen',
          color: pt.bg2,
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
              side: BorderSide(color: pt.border)),
          itemBuilder: (_) => buildMenuItems(),
          onSelected: handleMenu,
          child: Padding(
            padding: const EdgeInsets.all(8),
            child: Icon(Icons.add_rounded,
                color: hasBanner ? Colors.white70 : pt.fgDim, size: 18),
          ),
        ),
      ],
    );

    if (hasBanner) {
      return SizedBox(
        height: 110,
        child: Stack(
          fit: StackFit.expand,
          children: [
            // Banner image
            MxcImage(
              mxcUri: bannerUrl,
              client: client,
              fit: BoxFit.cover,
              placeholder: Container(color: pt.bg0),
            ),
            // Gradient overlay — bottom-heavy so text is readable
            DecoratedBox(
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  stops: [0.0, 0.4, 1.0],
                  colors: [
                    Color(0x00000000),
                    Color(0x55000000),
                    Color(0xCC000000),
                  ],
                ),
              ),
            ),
            // Controls at the bottom
            Positioned(
              left: 0,
              right: 0,
              bottom: 0,
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
                child: controlsRow,
              ),
            ),
            // Bottom border
            Positioned(
              left: 0,
              right: 0,
              bottom: 0,
              child: Container(height: 1, color: pt.border.withAlpha(80)),
            ),
          ],
        ),
      );
    }

    return Container(
      height: isRealSpace ? 56 : 52,
      padding: const EdgeInsets.symmetric(horizontal: 14),
      decoration: BoxDecoration(
        color: isRealSpace ? pt.bg0 : pt.bg1,
        border: Border(bottom: BorderSide(color: pt.border)),
      ),
      child: controlsRow,
    );
  }
}

class _MenuRow extends StatelessWidget {
  final IconData icon;
  final String label;
  final PyramidTheme pt;
  final bool danger;
  const _MenuRow(this.icon, this.label, this.pt, {this.danger = false});

  @override
  Widget build(BuildContext context) => Row(children: [
        Icon(icon, size: 14, color: danger ? pt.danger : pt.fgMuted),
        const SizedBox(width: 8),
        Text(label,
            style: TextStyle(
                color: danger ? pt.danger : pt.fg, fontSize: 13)),
      ]);
}

class _NotificationsButton extends ConsumerWidget {
  final PyramidTheme pt;
  final bool hasBanner;
  const _NotificationsButton({required this.pt, required this.hasBanner});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final rooms = ref.watch(roomListProvider).valueOrNull ?? [];
    final unread = rooms
        .where((r) =>
            r.membership == Membership.join &&
            (r.notificationCount > 0 || r.highlightCount > 0))
        .toList()
      ..sort((a, b) {
        final hl = b.highlightCount.compareTo(a.highlightCount);
        if (hl != 0) return hl;
        return b.notificationCount.compareTo(a.notificationCount);
      });

    return PopupMenuButton<String>(
      tooltip: 'Benachrichtigungen',
      color: pt.bg2,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10),
          side: BorderSide(color: pt.border)),
      offset: const Offset(0, 36),
      onSelected: (roomId) {
        ref.read(activeRoomIdProvider.notifier).state = roomId;
        ref.read(viewModeProvider.notifier).state = ViewMode.chat;
      },
      itemBuilder: (_) {
        if (unread.isEmpty) {
          return [
            PopupMenuItem<String>(
              enabled: false,
              child: Text('Keine neuen Benachrichtigungen',
                  style: TextStyle(color: pt.fgDim, fontSize: 13)),
            ),
          ];
        }
        return unread
            .map((r) => PopupMenuItem<String>(
                  value: r.id,
                  child: Row(
                    children: [
                      Icon(
                        r.highlightCount > 0
                            ? Icons.alternate_email_rounded
                            : (r.isDirectChat
                                ? Icons.chat_bubble_outline_rounded
                                : Icons.tag_rounded),
                        size: 14,
                        color:
                            r.highlightCount > 0 ? pt.danger : pt.fgMuted,
                      ),
                      const SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          r.getLocalizedDisplayname(),
                          style: TextStyle(color: pt.fg, fontSize: 13),
                          overflow: TextOverflow.ellipsis,
                        ),
                      ),
                      const SizedBox(width: 8),
                      Container(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 6, vertical: 1),
                        decoration: BoxDecoration(
                          color: r.highlightCount > 0 ? pt.danger : pt.accent,
                          borderRadius: BorderRadius.circular(999),
                        ),
                        child: Text(
                          '${r.notificationCount > 0 ? r.notificationCount : r.highlightCount}',
                          style: const TextStyle(
                              color: Colors.white,
                              fontSize: 10,
                              fontWeight: FontWeight.w700),
                        ),
                      ),
                    ],
                  ),
                ))
            .toList();
      },
      child: Padding(
        padding: const EdgeInsets.all(8),
        child: Stack(
          clipBehavior: Clip.none,
          children: [
            Icon(Icons.notifications_none_rounded,
                size: 18, color: hasBanner ? Colors.white70 : pt.fgDim),
            if (unread.isNotEmpty)
              Positioned(
                top: -1,
                right: -1,
                child: Container(
                  width: 8,
                  height: 8,
                  decoration: BoxDecoration(
                    color: pt.danger,
                    shape: BoxShape.circle,
                    border: Border.all(color: pt.bg1, width: 1.5),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

class _FilterInput extends StatelessWidget {
  final TextEditingController controller;
  final PyramidTheme pt;
  final ValueChanged<String> onChanged;
  const _FilterInput(
      {required this.controller, required this.pt, required this.onChanged});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 10, 12, 10),
      child: Stack(
        alignment: Alignment.centerLeft,
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 8),
            child: Icon(Icons.search_rounded, size: 14, color: pt.fgDim),
          ),
          TextField(
            controller: controller,
            onChanged: onChanged,
            style: TextStyle(color: pt.fg, fontSize: 13),
            decoration: InputDecoration(
              hintText: 'Filter rooms',
              hintStyle: TextStyle(color: pt.fgDim, fontSize: 13),
              contentPadding: const EdgeInsets.fromLTRB(28, 7, 10, 7),
              filled: true,
              fillColor: pt.bg2,
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(pt.rSm),
                  borderSide: BorderSide.none),
              enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(pt.rSm),
                  borderSide: const BorderSide(color: Colors.transparent)),
              focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(pt.rSm),
                  borderSide: BorderSide(color: pt.accent, width: 1)),
              isDense: true,
            ),
            cursorColor: pt.accent,
          ),
        ],
      ),
    );
  }
}
