import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:matrix/matrix.dart';
import 'package:pyramid/core/app_state.dart';
import 'package:pyramid/core/matrix_client.dart';
import 'package:pyramid/core/theme.dart';
import 'package:pyramid/widgets/mxc_image.dart';

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

  @override
  ConsumerState<NewDmDialog> createState() => _NewDmDialogState();
}

class _NewDmDialogState extends ConsumerState<NewDmDialog> {
  final _searchCtrl = TextEditingController();
  List<Profile> _results = [];
  bool _searching = false;
  String? _error;
  Timer? _debounce;
  final Set<String> _starting = {};

  @override
  void dispose() {
    _searchCtrl.dispose();
    _debounce?.cancel();
    super.dispose();
  }

  void _onSearchChanged(String query) {
    _debounce?.cancel();
    if (query.trim().length < 2) {
      setState(() {
        _results = [];
        _searching = false;
        _error = null;
      });
      return;
    }
    setState(() => _searching = true);
    _debounce = Timer(const Duration(milliseconds: 500), () => _search(query.trim()));
  }

  Future<void> _search(String query) async {
    try {
      final client = await ref.read(matrixClientProvider.future);
      final res = await client.searchUserDirectory(query, limit: 20);
      if (mounted) {
        setState(() {
          _results = res.results;
          _searching = false;
          _error = null;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _searching = false;
          _error = e.toString().split('\n').first;
        });
      }
    }
  }

  Future<void> _startDm(String userId) async {
    setState(() => _starting.add(userId));
    try {
      final client = await ref.read(matrixClientProvider.future);
      final roomId = await client.startDirectChat(userId);
      if (mounted) {
        ref.read(activeSpaceIdProvider.notifier).state = 'dms';
        ref.read(activeRoomIdProvider.notifier).state = roomId;
        ref.read(viewModeProvider.notifier).state = ViewMode.chat;
        Navigator.of(context).pop();
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _starting.remove(userId);
          _error = e.toString().split('\n').first;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    final size = MediaQuery.sizeOf(context);
    final isNarrow = size.width < 600;

    return Dialog(
      backgroundColor: pt.bg1,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(pt.rXl),
          side: BorderSide(color: pt.border)),
      child: ConstrainedBox(
        constraints: BoxConstraints(
          maxWidth: isNarrow ? size.width * 0.97 : 480,
          maxHeight: size.height * 0.75,
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(20, 16, 12, 12),
              child: Row(children: [
                Icon(Icons.chat_bubble_outline_rounded, size: 16, color: pt.accent),
                const SizedBox(width: 8),
                Expanded(
                  child: Text('Neue Unterhaltung',
                      style: TextStyle(
                          color: pt.fg,
                          fontSize: 15,
                          fontWeight: FontWeight.w600)),
                ),
                IconButton(
                  icon: Icon(Icons.close_rounded, color: pt.fgDim, size: 16),
                  onPressed: () => Navigator.of(context).pop(),
                  padding: EdgeInsets.zero,
                  constraints: const BoxConstraints(maxWidth: 28, maxHeight: 28),
                ),
              ]),
            ),
            Divider(color: pt.border, height: 1),
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
              child: TextField(
                controller: _searchCtrl,
                autofocus: true,
                style: TextStyle(color: pt.fg, fontSize: 13),
                onChanged: _onSearchChanged,
                decoration: InputDecoration(
                  hintText: 'Name oder @nutzer:server suchen',
                  hintStyle: TextStyle(color: pt.fgDim, fontSize: 13),
                  prefixIcon: Padding(
                    padding: const EdgeInsets.only(left: 10, right: 8),
                    child: Icon(Icons.search_rounded, size: 16, color: pt.fgDim),
                  ),
                  prefixIconConstraints:
                      const BoxConstraints(minWidth: 0, minHeight: 0),
                  filled: true,
                  fillColor: pt.bg2,
                  isDense: true,
                  contentPadding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(8),
                      borderSide: BorderSide(color: pt.border)),
                  enabledBorder: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(8),
                      borderSide: BorderSide(color: pt.border)),
                  focusedBorder: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(8),
                      borderSide: BorderSide(color: pt.accent)),
                ),
                cursorColor: pt.accent,
              ),
            ),
            if (_error != null)
              Padding(
                padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
                child: _DmErrorBanner(text: _error!, pt: pt),
              ),
            Flexible(
              child: _searching
                  ? const Padding(
                      padding: EdgeInsets.all(24),
                      child:
                          Center(child: CircularProgressIndicator.adaptive()),
                    )
                  : _results.isEmpty
                      ? Padding(
                          padding: const EdgeInsets.all(24),
                          child: Center(
                            child: Text(
                              _searchCtrl.text.trim().length < 2
                                  ? 'Mindestens 2 Zeichen eingeben.'
                                  : 'Keine Nutzer gefunden.',
                              style: TextStyle(
                                  color: pt.fgMuted, fontSize: 13),
                            ),
                          ),
                        )
                      : ListView.builder(
                          shrinkWrap: true,
                          padding:
                              const EdgeInsets.fromLTRB(8, 0, 8, 12),
                          itemCount: _results.length,
                          itemBuilder: (ctx, i) {
                            final user = _results[i];
                            return _UserResultItem(
                              profile: user,
                              pt: pt,
                              isStarting:
                                  _starting.contains(user.userId),
                              onTap: () => _startDm(user.userId),
                            );
                          },
                        ),
            ),
          ],
        ),
      ),
    );
  }
}

class _UserResultItem extends ConsumerWidget {
  final Profile profile;
  final PyramidTheme pt;
  final bool isStarting;
  final VoidCallback onTap;

  const _UserResultItem({
    required this.profile,
    required this.pt,
    required this.isStarting,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final client = ref.watch(matrixClientProvider).valueOrNull;
    final name = profile.displayName ?? profile.userId;
    final initial = name.isNotEmpty ? name[0].toUpperCase() : '?';

    Widget avatar;
    if (client != null && profile.avatarUrl != null) {
      avatar = MxcAvatar(
        mxcUri: profile.avatarUrl,
        client: client,
        size: 36,
        borderRadius: BorderRadius.circular(18),
        placeholder: (_) =>
            _DmInitialCircle(initial: initial, size: 36, name: name),
      );
    } else {
      avatar = _DmInitialCircle(initial: initial, size: 36, name: name);
    }

    return Material(
      color: Colors.transparent,
      child: InkWell(
        borderRadius: BorderRadius.circular(8),
        onTap: isStarting ? null : onTap,
        child: Padding(
          padding:
              const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
          child: Row(children: [
            avatar,
            const SizedBox(width: 10),
            Expanded(
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(name,
                        style: TextStyle(
                            color: pt.fg,
                            fontSize: 13,
                            fontWeight: FontWeight.w500),
                        overflow: TextOverflow.ellipsis),
                    Text(profile.userId,
                        style:
                            TextStyle(color: pt.fgDim, fontSize: 11),
                        overflow: TextOverflow.ellipsis),
                  ]),
            ),
            const SizedBox(width: 8),
            if (isStarting)
              const SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator.adaptive(
                      strokeWidth: 2))
            else
              Icon(Icons.arrow_forward_rounded,
                  size: 14, color: pt.fgDim),
          ]),
        ),
      ),
    );
  }
}

class _DmInitialCircle extends StatelessWidget {
  final String initial;
  final double size;
  final String name;

  const _DmInitialCircle(
      {required this.initial, required this.size, required this.name});

  Color _color() {
    const colors = [
      Color(0xFF06B6D4), Color(0xFFA855F7), Color(0xFF10B981),
      Color(0xFFF43F5E), Color(0xFF3B82F6), Color(0xFFF59E0B),
    ];
    if (name.isEmpty) return colors[0];
    return colors[name.codeUnitAt(0) % colors.length];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: size,
      height: size,
      decoration: BoxDecoration(color: _color(), shape: BoxShape.circle),
      child: Center(
        child: Text(initial,
            style: const TextStyle(
                color: Colors.white,
                fontSize: 14,
                fontWeight: FontWeight.w600)),
      ),
    );
  }
}

class _DmErrorBanner extends StatelessWidget {
  final String text;
  final PyramidTheme pt;
  const _DmErrorBanner({required this.text, required this.pt});

  @override
  Widget build(BuildContext context) => Container(
        padding:
            const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
        decoration: BoxDecoration(
          color: pt.danger.withAlpha(20),
          borderRadius: BorderRadius.circular(8),
          border: Border.all(color: pt.danger.withAlpha(60)),
        ),
        child: Row(children: [
          Icon(Icons.error_outline_rounded, size: 14, color: pt.danger),
          const SizedBox(width: 8),
          Expanded(
              child: Text(text,
                  style:
                      TextStyle(color: pt.danger, fontSize: 12))),
        ]),
      );
}
