part of '../space_admin_dialog.dart';

const _kSpaceChild = 'm.space.child';
const _kSpaceParent = 'm.space.parent';
const _kVoiceChannelType = 'io.pyramid.voice_channel';

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

  @override
  ConsumerState<_ChannelsTab> createState() => _ChannelsTabState();
}

class _ChannelsTabState extends ConsumerState<_ChannelsTab> {
  bool _busy = false;

  List<({String roomId, Room? room, bool isVoice})> _getChildren(Client client) {
    final childStates = widget.space.states[_kSpaceChild] ?? {};
    final result = <({String roomId, Room? room, bool isVoice})>[];
    for (final entry in childStates.entries) {
      final content = entry.value.content;
      if (content.isEmpty) continue;
      final childRoomId = entry.key;
      final room = client.getRoomById(childRoomId);
      final createContent = room?.getState('m.room.create')?.content;
      final isVoice = createContent?['type'] == _kVoiceChannelType;
      result.add((roomId: childRoomId, room: room, isVoice: isVoice));
    }
    result.sort((a, b) {
      final nameA = a.room?.getLocalizedDisplayname() ?? a.roomId;
      final nameB = b.room?.getLocalizedDisplayname() ?? b.roomId;
      return nameA.compareTo(nameB);
    });
    return result;
  }

  Future<void> _removeChild(String roomId) async {
    final client = ref.read(matrixClientProvider).valueOrNull;
    if (client == null) return;
    setState(() => _busy = true);
    try {
      await client.setRoomStateWithKey(widget.space.id, _kSpaceChild, roomId, {});
      if (mounted) setState(() {});
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(e.toString())));
      }
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  Future<void> _addChild(String roomId) async {
    final client = ref.read(matrixClientProvider).valueOrNull;
    if (client == null) return;
    final serverName = client.userID?.split(':').last ?? '';
    try {
      await client.setRoomStateWithKey(
        widget.space.id,
        _kSpaceChild,
        roomId,
        {'via': [serverName], 'suggested': false},
      );
      // Best-effort: set parent in child room
      try {
        await client.setRoomStateWithKey(
          roomId,
          _kSpaceParent,
          widget.space.id,
          {'via': [serverName], 'canonical': true},
        );
      } catch (_) {}
      if (mounted) setState(() {});
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(e.toString())));
      }
    }
  }

  Future<void> _createAndAdd({
    required String name,
    required bool isVoice,
    required Client client,
  }) async {
    setState(() => _busy = true);
    try {
      final serverName = client.userID?.split(':').last ?? '';
      final roomId = await client.createRoom(
        name: name,
        visibility: Visibility.private,
        preset: CreateRoomPreset.privateChat,
        creationContent: isVoice ? {'type': _kVoiceChannelType} : null,
        initialState: [
          StateEvent(
            type: 'm.room.join_rules',
            content: {'join_rule': 'restricted', 'allow': [
              {'type': 'm.room_membership', 'room_id': widget.space.id}
            ]},
          ),
        ],
      );
      await client.setRoomStateWithKey(
        widget.space.id,
        _kSpaceChild,
        roomId,
        {'via': [serverName], 'suggested': false},
      );
      try {
        await client.setRoomStateWithKey(
          roomId,
          _kSpaceParent,
          widget.space.id,
          {'via': [serverName], 'canonical': true},
        );
      } catch (_) {}
      if (mounted) setState(() {});
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(e.toString())));
      }
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  void _showCreateDialog(BuildContext context, Client client) {
    showDialog(
      context: context,
      builder: (_) => _CreateChannelDialog(
        onConfirm: (name, isVoice) =>
            _createAndAdd(name: name, isVoice: isVoice, client: client),
      ),
    );
  }

  void _showAddExistingDialog(BuildContext context, Client client) {
    final childStates = widget.space.states[_kSpaceChild] ?? {};
    final existingIds = {
      for (final e in childStates.entries)
        if (e.value.content.isNotEmpty) e.key
    };
    final available = client.rooms
        .where((r) => !r.isSpace && !existingIds.contains(r.id))
        .toList()
      ..sort((a, b) => a.getLocalizedDisplayname()
          .compareTo(b.getLocalizedDisplayname()));

    showDialog(
      context: context,
      builder: (_) => _AddExistingDialog(
        rooms: available,
        client: client,
        onConfirm: (roomId) => _addChild(roomId),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    final client = ref.watch(matrixClientProvider).valueOrNull;
    final ownPower = widget.space.ownPowerLevel;
    final canManage = ownPower >= _kPowerMod;

    if (client == null) {
      return Center(
          child: CircularProgressIndicator(color: pt.accent, strokeWidth: 2));
    }

    final children = _getChildren(client);

    return Column(
      children: [
        if (canManage)
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 12, 16, 4),
            child: Row(
              children: [
                Expanded(
                  child: OutlinedButton.icon(
                    icon: const Icon(Icons.add, size: 16),
                    label: const Text('Kanal erstellen'),
                    style: OutlinedButton.styleFrom(
                      foregroundColor: pt.accent,
                      side: BorderSide(color: pt.accent),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(pt.rSm)),
                    ),
                    onPressed: _busy
                        ? null
                        : () => _showCreateDialog(context, client),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: OutlinedButton.icon(
                    icon: const Icon(Icons.link, size: 16),
                    label: const Text('Raum hinzufügen'),
                    style: OutlinedButton.styleFrom(
                      foregroundColor: pt.fgDim,
                      side: BorderSide(color: pt.border),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(pt.rSm)),
                    ),
                    onPressed: _busy
                        ? null
                        : () => _showAddExistingDialog(context, client),
                  ),
                ),
              ],
            ),
          ),
        if (children.isEmpty)
          Expanded(
            child: Center(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Icon(Icons.forum_outlined, color: pt.fgDim, size: 40),
                  const SizedBox(height: 8),
                  Text('Noch keine Kanäle',
                      style: TextStyle(color: pt.fgDim, fontSize: 13)),
                ],
              ),
            ),
          )
        else
          Expanded(
            child: ListView.builder(
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
              itemCount: children.length,
              itemBuilder: (context, i) {
                final child = children[i];
                final name = child.room?.getLocalizedDisplayname() ??
                    child.roomId;
                return _ChannelItem(
                  name: name,
                  isVoice: child.isVoice,
                  roomId: child.roomId,
                  pt: pt,
                  canRemove: canManage,
                  onRemove: () => _removeChild(child.roomId),
                );
              },
            ),
          ),
      ],
    );
  }
}

class _ChannelItem extends StatefulWidget {
  final String name;
  final bool isVoice;
  final String roomId;
  final PyramidTheme pt;
  final bool canRemove;
  final VoidCallback onRemove;

  const _ChannelItem({
    required this.name,
    required this.isVoice,
    required this.roomId,
    required this.pt,
    required this.canRemove,
    required this.onRemove,
  });

  @override
  State<_ChannelItem> createState() => _ChannelItemState();
}

class _ChannelItemState extends State<_ChannelItem> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    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: 10, vertical: 0),
          leading: Icon(
            widget.isVoice
                ? Icons.volume_up_outlined
                : Icons.tag,
            color: pt.fgDim,
            size: 18,
          ),
          title: Text(
            widget.name,
            style: TextStyle(
                color: pt.fg, fontSize: 13, fontWeight: FontWeight.w500),
            overflow: TextOverflow.ellipsis,
          ),
          subtitle: Text(
            widget.isVoice ? 'Sprachkanal' : 'Textkanal',
            style: TextStyle(color: pt.fgDim, fontSize: 11),
          ),
          trailing: widget.canRemove && _hovered
              ? IconButton(
                  icon: Icon(Icons.link_off,
                      color: const Color(0xFFED4245), size: 18),
                  tooltip: 'Aus Space entfernen',
                  onPressed: widget.onRemove,
                )
              : null,
        ),
      ),
    );
  }
}

class _CreateChannelDialog extends StatefulWidget {
  final void Function(String name, bool isVoice) onConfirm;
  const _CreateChannelDialog({required this.onConfirm});

  @override
  State<_CreateChannelDialog> createState() => _CreateChannelDialogState();
}

class _CreateChannelDialogState extends State<_CreateChannelDialog> {
  final _ctrl = TextEditingController();
  bool _isVoice = false;

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

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    return AlertDialog(
      backgroundColor: pt.bg1,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(pt.rLg)),
      title: Text('Neuen Kanal erstellen',
          style: TextStyle(color: pt.fg, fontWeight: FontWeight.w700)),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _SectionLabel('Name', pt),
          const SizedBox(height: 6),
          _Field(controller: _ctrl, hint: 'kanal-name', pt: pt),
          const SizedBox(height: 16),
          _SectionLabel('Typ', pt),
          const SizedBox(height: 8),
          Row(
            children: [
              Expanded(
                child: GestureDetector(
                  onTap: () => setState(() => _isVoice = false),
                  child: Container(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 12, vertical: 10),
                    decoration: BoxDecoration(
                      color: !_isVoice ? pt.accent.withAlpha(40) : pt.bg0,
                      border: Border.all(
                          color: !_isVoice ? pt.accent : pt.border),
                      borderRadius: BorderRadius.circular(pt.rSm),
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.tag,
                            color: !_isVoice ? pt.accent : pt.fgDim,
                            size: 16),
                        const SizedBox(width: 6),
                        Text('Text',
                            style: TextStyle(
                                color: !_isVoice ? pt.accent : pt.fgDim,
                                fontSize: 13,
                                fontWeight: FontWeight.w600)),
                      ],
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: GestureDetector(
                  onTap: () => setState(() => _isVoice = true),
                  child: Container(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 12, vertical: 10),
                    decoration: BoxDecoration(
                      color: _isVoice ? pt.accent.withAlpha(40) : pt.bg0,
                      border: Border.all(
                          color: _isVoice ? pt.accent : pt.border),
                      borderRadius: BorderRadius.circular(pt.rSm),
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.volume_up_outlined,
                            color: _isVoice ? pt.accent : pt.fgDim,
                            size: 16),
                        const SizedBox(width: 6),
                        Text('Sprache',
                            style: TextStyle(
                                color: _isVoice ? pt.accent : pt.fgDim,
                                fontSize: 13,
                                fontWeight: FontWeight.w600)),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
      actions: [
        TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Abbrechen')),
        FilledButton(
          style: FilledButton.styleFrom(backgroundColor: pt.accent),
          onPressed: () {
            final name = _ctrl.text.trim();
            if (name.isEmpty) return;
            Navigator.pop(context);
            widget.onConfirm(name, _isVoice);
          },
          child: const Text('Erstellen',
              style: TextStyle(color: Colors.white)),
        ),
      ],
    );
  }
}

class _AddExistingDialog extends StatefulWidget {
  final List<Room> rooms;
  final Client client;
  final void Function(String roomId) onConfirm;

  const _AddExistingDialog({
    required this.rooms,
    required this.client,
    required this.onConfirm,
  });

  @override
  State<_AddExistingDialog> createState() => _AddExistingDialogState();
}

class _AddExistingDialogState extends State<_AddExistingDialog> {
  String _filter = '';
  final _ctrl = TextEditingController();

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

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    final filtered = _filter.isEmpty
        ? widget.rooms
        : widget.rooms
            .where((r) => r
                .getLocalizedDisplayname()
                .toLowerCase()
                .contains(_filter.toLowerCase()))
            .toList();

    return Dialog(
      backgroundColor: pt.bg1,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(pt.rLg)),
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 400, maxHeight: 520),
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(20, 20, 20, 12),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Expanded(
                        child: Text('Raum hinzufügen',
                            style: TextStyle(
                                color: pt.fg,
                                fontSize: 17,
                                fontWeight: FontWeight.w700)),
                      ),
                      IconButton(
                        icon: Icon(Icons.close, color: pt.fgDim, size: 20),
                        onPressed: () => Navigator.pop(context),
                      ),
                    ],
                  ),
                  const SizedBox(height: 12),
                  _SearchField(
                    controller: _ctrl,
                    hint: 'Raum suchen…',
                    pt: pt,
                    onChanged: (v) => setState(() => _filter = v),
                  ),
                ],
              ),
            ),
            const Divider(height: 1),
            if (filtered.isEmpty)
              Expanded(
                child: Center(
                  child: Text('Keine Räume gefunden',
                      style: TextStyle(color: pt.fgDim, fontSize: 13)),
                ),
              )
            else
              Expanded(
                child: ListView.builder(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 8, vertical: 4),
                  itemCount: filtered.length,
                  itemBuilder: (context, i) {
                    final room = filtered[i];
                    final name = room.getLocalizedDisplayname();
                    final letter =
                        name.isNotEmpty ? name[0].toUpperCase() : '?';
                    final avatarUri = room.avatar;
                    final createContent =
                        room.getState('m.room.create')?.content;
                    final isVoice =
                        createContent?['type'] == _kVoiceChannelType;
                    return ListTile(
                      dense: true,
                      leading: avatarUri != null
                          ? MxcAvatar(
                              mxcUri: avatarUri,
                              client: widget.client,
                              size: 32,
                              borderRadius: BorderRadius.circular(pt.rSm),
                              placeholder: (_) => _InitialAvatar(
                                  letter: letter, pt: pt, size: 32),
                            )
                          : _InitialAvatar(letter: letter, pt: pt, size: 32),
                      title: Text(name,
                          style: TextStyle(
                              color: pt.fg,
                              fontSize: 13,
                              fontWeight: FontWeight.w500),
                          overflow: TextOverflow.ellipsis),
                      subtitle: Text(
                        isVoice ? 'Sprachkanal' : 'Textkanal',
                        style: TextStyle(color: pt.fgDim, fontSize: 11),
                      ),
                      trailing:
                          Icon(isVoice ? Icons.volume_up_outlined : Icons.tag,
                              color: pt.fgDim, size: 16),
                      onTap: () {
                        Navigator.pop(context);
                        widget.onConfirm(room.id);
                      },
                    );
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }
}
