part of '../space_admin_dialog.dart';

class _MembersTab extends ConsumerStatefulWidget {
  final Room space;
  const _MembersTab({required this.space});

  @override
  ConsumerState<_MembersTab> createState() => _MembersTabState();
}

class _MembersTabState extends ConsumerState<_MembersTab> {
  List<User>? _members;
  bool _loading = true;
  String? _error;
  String _filter = '';
  final _filterCtrl = TextEditingController();

  @override
  void initState() {
    super.initState();
    _load();
  }

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

  Future<void> _load() async {
    try {
      final members =
          await widget.space.requestParticipants([Membership.join, Membership.invite]);
      if (mounted) setState(() { _members = members; _loading = false; });
    } catch (e) {
      if (mounted) setState(() { _error = e.toString(); _loading = false; });
    }
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);

    if (_loading) {
      return Center(
          child: CircularProgressIndicator(color: pt.accent, strokeWidth: 2));
    }
    if (_error != null) {
      return Center(
          child: Text(_error!, style: TextStyle(color: pt.fgDim, fontSize: 13)));
    }

    final members = _members ?? [];
    final filtered = _filter.isEmpty
        ? members
        : members
            .where((m) =>
                (m.displayName ?? m.id)
                    .toLowerCase()
                    .contains(_filter.toLowerCase()) ||
                m.id.toLowerCase().contains(_filter.toLowerCase()))
            .toList()
      ..sort((a, b) => (b.powerLevel).compareTo(a.powerLevel));

    final ownPower = widget.space.ownPowerLevel;

    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
          child: Row(
            children: [
              Expanded(
                child: _SearchField(
                  controller: _filterCtrl,
                  hint: 'Mitglieder suchen…',
                  pt: pt,
                  onChanged: (v) => setState(() => _filter = v),
                ),
              ),
              if (ownPower >= _kPowerMod) ...[
                const SizedBox(width: 8),
                _InviteButton(space: widget.space),
              ],
            ],
          ),
        ),
        Expanded(
          child: ListView.builder(
            padding: const EdgeInsets.symmetric(horizontal: 8),
            itemCount: filtered.length,
            itemBuilder: (context, i) {
              final member = filtered[i];
              return _MemberTile(
                member: member,
                space: widget.space,
                ownPower: ownPower,
                onChanged: _load,
              );
            },
          ),
        ),
      ],
    );
  }
}

class _InviteButton extends ConsumerStatefulWidget {
  final Room space;
  const _InviteButton({required this.space});

  @override
  ConsumerState<_InviteButton> createState() => _InviteButtonState();
}

class _InviteButtonState extends ConsumerState<_InviteButton> {
  bool _inviting = false;
  String? _inviteError;

  void _showInvite() {
    final pt = PyramidTheme.of(context);
    final ctrl = TextEditingController();
    showDialog(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (ctx, setS) => AlertDialog(
          backgroundColor: pt.bg1,
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(pt.rLg)),
          title: Text('Zu Space einladen',
              style: TextStyle(color: pt.fg, fontWeight: FontWeight.w700)),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _Field(controller: ctrl, hint: '@user:server.org', pt: pt),
              const SizedBox(height: 6),
              Text('Lädt zu Space und allen Kanälen ein.',
                  style: TextStyle(color: pt.fgDim, fontSize: 11)),
              if (_inviteError != null) ...[
                const SizedBox(height: 6),
                Text(_inviteError!,
                    style: TextStyle(color: pt.danger, fontSize: 12)),
              ],
            ],
          ),
          actions: [
            TextButton(
                onPressed: () => Navigator.pop(ctx),
                child: const Text('Abbrechen')),
            FilledButton(
              style: FilledButton.styleFrom(backgroundColor: pt.accent),
              onPressed: _inviting
                  ? null
                  : () async {
                      final userId = ctrl.text.trim();
                      if (userId.isEmpty) return;
                      setS(() { _inviting = true; _inviteError = null; });
                      try {
                        // 1. Invite to space itself
                        await widget.space.invite(userId);
                        // 2. Invite to every joined child room
                        final client = widget.space.client;
                        for (final child in widget.space.spaceChildren) {
                          final roomId = child.roomId;
                          if (roomId == null) continue;
                          final room = client.getRoomById(roomId);
                          if (room == null || room.membership == Membership.leave) continue;
                          try {
                            await room.invite(userId);
                          } catch (_) {}
                        }
                        if (ctx.mounted) Navigator.pop(ctx);
                      } catch (e) {
                        setS(() { _inviteError = e.toString().split('\n').first; });
                      } finally {
                        setS(() => _inviting = false);
                      }
                    },
              child: _inviting
                  ? const SizedBox(
                      width: 16, height: 16,
                      child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white))
                  : const Text('Einladen',
                      style: TextStyle(color: Colors.white)),
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    return IconButton(
      icon: Icon(Icons.person_add_outlined, color: pt.accent, size: 20),
      tooltip: 'Einladen',
      onPressed: _showInvite,
    );
  }
}

class _MemberTile extends ConsumerStatefulWidget {
  final User member;
  final Room space;
  final int ownPower;
  final VoidCallback onChanged;

  const _MemberTile({
    required this.member,
    required this.space,
    required this.ownPower,
    required this.onChanged,
  });

  @override
  ConsumerState<_MemberTile> createState() => _MemberTileState();
}

class _MemberTileState extends ConsumerState<_MemberTile> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    final member = widget.member;
    final power = member.powerLevel;
    final name = member.displayName ?? member.id;
    final client = ref.watch(matrixClientProvider).valueOrNull;
    final avatarUri = member.avatarUrl;
    final isMe = member.id == widget.space.client.userID;
    final canManage = widget.ownPower > power && !isMe;

    Widget avatar;
    final letter = name.isNotEmpty ? name[0].toUpperCase() : '?';
    if (client != null && avatarUri != null) {
      avatar = MxcAvatar(
        mxcUri: avatarUri,
        client: client,
        size: 32,
        borderRadius: BorderRadius.circular(16),
        placeholder: (_) => _InitialAvatar(letter: letter, pt: pt, size: 32),
      );
    } else {
      avatar = _InitialAvatar(letter: letter, pt: pt, size: 32);
    }

    return MouseRegion(
      onEnter: (_) => setState(() => _hovered = true),
      onExit: (_) => setState(() => _hovered = false),
      child: Container(
        margin: const EdgeInsets.symmetric(vertical: 1),
        decoration: BoxDecoration(
          color: _hovered ? pt.bg2 : Colors.transparent,
          borderRadius: BorderRadius.circular(pt.rSm),
        ),
        child: ListTile(
          dense: true,
          contentPadding: const EdgeInsets.symmetric(horizontal: 8),
          leading: avatar,
          title: Text(name,
              style: TextStyle(
                  color: pt.fg,
                  fontSize: 13,
                  fontWeight: FontWeight.w500),
              overflow: TextOverflow.ellipsis),
          subtitle: Text(member.id,
              style: TextStyle(color: pt.fgDim, fontSize: 11),
              overflow: TextOverflow.ellipsis),
          trailing: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
                decoration: BoxDecoration(
                  color: _powerColor(power, pt).withAlpha(30),
                  borderRadius: BorderRadius.circular(6),
                ),
                child: Text(_powerLabel(power),
                    style: TextStyle(
                        color: _powerColor(power, pt),
                        fontSize: 11,
                        fontWeight: FontWeight.w600)),
              ),
              if (canManage) ...[
                const SizedBox(width: 4),
                _MemberActions(
                    member: member,
                    space: widget.space,
                    ownPower: widget.ownPower,
                    onChanged: widget.onChanged),
              ],
            ],
          ),
        ),
      ),
    );
  }
}

class _MemberActions extends ConsumerWidget {
  final User member;
  final Room space;
  final int ownPower;
  final VoidCallback onChanged;

  const _MemberActions({
    required this.member,
    required this.space,
    required this.ownPower,
    required this.onChanged,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final pt = PyramidTheme.of(context);
    return PopupMenuButton<_MemberAction>(
      icon: Icon(Icons.more_vert, color: pt.fgDim, size: 18),
      color: pt.bg2,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(pt.rBase)),
      itemBuilder: (_) => [
        if (ownPower >= _kPowerAdmin && member.powerLevel < _kPowerMod)
          const PopupMenuItem(
            value: _MemberAction.makeMod,
            child: Text('Zum Moderator machen'),
          ),
        if (ownPower >= _kPowerAdmin && member.powerLevel == _kPowerMod)
          const PopupMenuItem(
            value: _MemberAction.removeMod,
            child: Text('Moderator-Rechte entziehen'),
          ),
        if (ownPower >= _kPowerAdmin && member.powerLevel < _kPowerAdmin)
          const PopupMenuItem(
            value: _MemberAction.makeAdmin,
            child: Text('Zum Admin machen'),
          ),
        const PopupMenuItem(
          value: _MemberAction.kick,
          child: Text('Kicken', style: TextStyle(color: Color(0xFFF59E0B))),
        ),
        const PopupMenuItem(
          value: _MemberAction.ban,
          child: Text('Bannen', style: TextStyle(color: Color(0xFFED4245))),
        ),
      ],
      onSelected: (action) => _handleAction(context, action),
    );
  }

  Future<void> _handleAction(BuildContext context, _MemberAction action) async {
    switch (action) {
      case _MemberAction.makeMod:
        await _setPower(context, _kPowerMod);
      case _MemberAction.removeMod:
        await _setPower(context, _kPowerMember);
      case _MemberAction.makeAdmin:
        _confirmAdmin(context);
      case _MemberAction.kick:
        _confirmKick(context);
      case _MemberAction.ban:
        _confirmBan(context);
    }
  }

  Future<void> _setPower(BuildContext context, int level) async {
    try {
      // NICHT space.setPower() — das merged nur mit dem lokalen Cache und
      // kann die users-Map des Servers zerstören (Admin-Aussperrung).
      await updatePowerLevelsSafely(space, (content) {
        (content['users'] as Map<String, dynamic>)[member.id] = level;
      });
      onChanged();
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(e.toString())));
      }
    }
  }

  void _confirmAdmin(BuildContext context) {
    showDialog(
      context: context,
      builder: (_) => AlertDialog(
        title: const Text('Admin machen?'),
        content: Text(
            '${member.displayName ?? member.id} zum Admin befördern? '
            'Admin-Rechte können nicht einfach entzogen werden.'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Abbrechen')),
          TextButton(
            onPressed: () async {
              Navigator.pop(context);
              await _setPower(context, _kPowerAdmin);
            },
            child: const Text('Admin machen',
                style: TextStyle(color: Color(0xFFED4245))),
          ),
        ],
      ),
    );
  }

  void _confirmKick(BuildContext context) {
    showDialog(
      context: context,
      builder: (_) => AlertDialog(
        title: const Text('Mitglied kicken?'),
        content: Text('${member.displayName ?? member.id} aus dem Space entfernen?'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Abbrechen')),
          TextButton(
            onPressed: () async {
              Navigator.pop(context);
              try {
                await space.kick(member.id);
                onChanged();
              } catch (_) {}
            },
            child: const Text('Kicken',
                style: TextStyle(color: Color(0xFFF59E0B))),
          ),
        ],
      ),
    );
  }

  void _confirmBan(BuildContext context) {
    showDialog(
      context: context,
      builder: (_) => AlertDialog(
        title: const Text('Mitglied bannen?'),
        content: Text(
            '${member.displayName ?? member.id} dauerhaft aus dem Space ausschließen?'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Abbrechen')),
          TextButton(
            onPressed: () async {
              Navigator.pop(context);
              try {
                await space.ban(member.id);
                onChanged();
              } catch (_) {}
            },
            child: const Text('Bannen',
                style: TextStyle(color: Color(0xFFED4245))),
          ),
        ],
      ),
    );
  }
}

enum _MemberAction { makeMod, removeMod, makeAdmin, kick, ban }
