part of '../rooms_panel.dart';

const _kVoiceRoomType = 'io.pyramid.voice_channel';

const _kSpaceBannerType = 'io.pyramid.space.banner';

bool _isVoiceRoom(Room room) =>
    room.getState(EventTypes.RoomCreate)?.content['type'] == _kVoiceRoomType;

int _compareSpaceChildren(SpaceChild a, SpaceChild b) {
  final ao = a.order;
  final bo = b.order;
  if (ao.isEmpty && bo.isEmpty) return 0;
  if (ao.isEmpty) return 1;
  if (bo.isEmpty) return -1;
  return ao.compareTo(bo);
}

class RoomsPanel extends ConsumerStatefulWidget {
  const RoomsPanel({super.key});

  @override
  ConsumerState<RoomsPanel> createState() => _RoomsPanelState();
}

class _RoomsPanelState extends ConsumerState<RoomsPanel> {
  final _filterCtrl = TextEditingController();
  String _filter = '';
  final Map<String, bool> _collapsed = {};

  @override
  void dispose() {
    _filterCtrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    final roomsAsync = ref.watch(roomListProvider);
    final activeSpaceId = ref.watch(activeSpaceIdProvider);
    final call = ref.watch(callStateProvider);
    final voip = ref.watch(voipStateProvider);

    final isRealSpace = activeSpaceId != null &&
        activeSpaceId != 'dms' &&
        activeSpaceId != 'rooms';

    final client = ref.watch(matrixClientProvider).valueOrNull;
    final forceJoined = ref.watch(forceJoinedSpacesProvider);
    final activeSpaceRoom =
        isRealSpace ? client?.getRoomById(activeSpaceId) : null;
    final isInvitedSpace = activeSpaceRoom?.membership == Membership.invite &&
        !forceJoined.contains(activeSpaceId);

    return Container(
      color: pt.bg1,
      child: Column(
        children: [
          _Header(pt: pt, spaceId: activeSpaceId),
          if (!isInvitedSpace)
            _FilterInput(
              controller: _filterCtrl,
              pt: pt,
              onChanged: (v) => setState(() => _filter = v),
            ),
          Expanded(
            child: isInvitedSpace
                ? _SpaceInviteView(space: activeSpaceRoom!, pt: pt)
                : isRealSpace
                ? _SpaceRoomsList(
                    spaceId: activeSpaceId,
                    filter: _filter,
                    collapsed: _collapsed,
                    pt: pt,
                    onToggleSection: (id) => setState(() {
                      _collapsed[id] = !(_collapsed[id] ?? false);
                    }),
                  )
                : roomsAsync.when(
                    loading: () => Center(
                      child: SizedBox(
                        width: 20,
                        height: 20,
                        child: CircularProgressIndicator(
                            strokeWidth: 2, color: pt.accent),
                      ),
                    ),
                    error: (e, _) => Center(
                      child: Text('Error',
                          style: TextStyle(color: pt.fgDim, fontSize: 12)),
                    ),
                    data: (rooms) => _RoomsList(
                      rooms: rooms,
                      filter: _filter,
                      spaceId: activeSpaceId,
                      collapsed: _collapsed,
                      pt: pt,
                      onToggleSection: (id) => setState(() {
                        _collapsed[id] = !(_collapsed[id] ?? false);
                      }),
                    ),
                  ),
          ),
          // Call-Dock: immer ÜBER dem Konto-Balken, animiert ein-/ausblenden.
          // Im Mobil-Querformat (Höhe knapp) liegen Call-Balken und
          // Konto-Balken nebeneinander statt übereinander.
          Builder(builder: (context) {
            final hasVoipCall = voip.currentCall != null &&
                voip.currentCall!.state != CallState.kEnded;
            final hasCallDock = call.isActive || hasVoipCall;
            final isLandscapeCompact =
                MediaQuery.sizeOf(context).height < 500;

            final callDock = AnimatedSize(
              duration: const Duration(milliseconds: 220),
              curve: Curves.easeOutCubic,
              alignment: Alignment.bottomCenter,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  if (call.isActive) MiniCallWidget(call: call),
                  if (hasVoipCall) MiniCallWidget(call: voip),
                ],
              ),
            );

            if (isLandscapeCompact && hasCallDock) {
              return Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Expanded(child: callDock),
                  const Expanded(child: UserPanel()),
                ],
              );
            }
            return Column(
              mainAxisSize: MainAxisSize.min,
              children: [callDock, const UserPanel()],
            );
          }),
        ],
      ),
    );
  }
}
