import 'dart:async';
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'chat_repository.dart';
import '../../data/message_model.dart';
import '../../core/auth_storage.dart';
import '../profile/profile_screen.dart';

class ChatScreen extends ConsumerStatefulWidget {
  final Conversation conversation;
  final String? anonToken;
  final String? visitorUserId;
  final String? initialLastMessage;
  final DateTime? initialLastMessageAt;

  const ChatScreen(
      {super.key,
      required this.conversation,
      this.anonToken,
      this.visitorUserId,
      this.initialLastMessage,
      this.initialLastMessageAt});

  @override
  ConsumerState<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends ConsumerState<ChatScreen>
    with WidgetsBindingObserver {
  final _controller = TextEditingController();
  final _scrollController = ScrollController();
  final List<Message> _messages = [];
  Timer? _timer;
  int _lastMessageId = 0;
  String? _myUserId;
  String? _currentAnonToken; // State variable for dynamic token update
  late final ChatRepository _chatRepository;
  late int _conversationId;
  bool _loading = true;
  final Duration _foregroundPollInterval = const Duration(seconds: 2);
  final Duration _backgroundPollInterval = const Duration(seconds: 10);
  bool _isForeground = true;
  bool _submittingReport = false;
  bool _loadingBlockStatus = false;
  bool _iBlockedThisUser = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _conversationId = widget.conversation.id;
    _currentAnonToken = widget.anonToken; // Init with widget param
    _setupRepository();
    if (_conversationId > 0) {
      _injectInitialPlaceholderMessage();
      _loadInitialBlockStatus();
      _loadInitialMessages();
      _restartPolling();
    } else {
      _loading = false;
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    final nextForeground = state == AppLifecycleState.resumed;
    if (_isForeground == nextForeground) return;
    _isForeground = nextForeground;
    if (_conversationId > 0) _restartPolling();
  }

  void _setupRepository() {
    if (_currentAnonToken != null) {
      // Use anon token (static client setup, but token might change)
      // Actually, we should use the main client but pass token in methods now
      _chatRepository = ref.read(chatRepositoryProvider);

      if (widget.visitorUserId != null) {
        _myUserId = widget.visitorUserId;
      } else {
        _myUserId = _getUserIdFromToken(_currentAnonToken!);
      }
    } else {
      _chatRepository = ref.read(chatRepositoryProvider);
      _loadMyUserId();
    }
  }

  String? _getUserIdFromToken(String token) {
    try {
      final parts = token.split('.');
      if (parts.length != 3) return null;
      final payload = parts[1];
      String normalized = base64Url.normalize(payload);
      final String decoded = utf8.decode(base64Url.decode(normalized));
      final Map<String, dynamic> json = jsonDecode(decoded);
      return json['sub']?.toString();
    } catch (e) {
      return null;
    }
  }

  Future<void> _loadMyUserId() async {
    if (_myUserId != null) return;
    _myUserId = await ref.read(authStorageProvider).getUserId();
    if (mounted) setState(() {});
  }

  @override
  void dispose() {
    _timer?.cancel();
    _controller.dispose();
    _scrollController.dispose();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  void _scrollToBottom({bool animated = true}) {
    if (!_scrollController.hasClients) return;
    final position = _scrollController.position;
    final target = position.maxScrollExtent;
    if (animated) {
      _scrollController.animateTo(
        target,
        duration: const Duration(milliseconds: 220),
        curve: Curves.easeOut,
      );
    } else {
      _scrollController.jumpTo(target);
    }
  }

  void _afterLayoutScroll() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _scrollToBottom(animated: false);
    });
  }

  String _formatTime(DateTime dt) {
    final h = dt.hour.toString().padLeft(2, '0');
    final m = dt.minute.toString().padLeft(2, '0');
    return '$h:$m';
  }

  void _injectInitialPlaceholderMessage() {
    final text = widget.initialLastMessage?.trim();
    if (text == null || text.isEmpty) return;
    if (_messages.isNotEmpty) return;

    final otherUserId = widget.conversation.otherUser['id'];
    final senderId = otherUserId is int
        ? otherUserId
        : int.tryParse(otherUserId?.toString() ?? '') ?? 0;
    final createdAt = widget.initialLastMessageAt ??
        widget.conversation.lastMessageAt ??
        DateTime.now();

    final placeholder = Message(
      id: -DateTime.now().millisecondsSinceEpoch,
      conversationId: _conversationId,
      senderId: senderId,
      bodyText: text,
      isAnonymous: widget.conversation.isAnonymous,
      createdAt: createdAt,
      isRead: true,
    );

    _messages.add(placeholder);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _scrollToBottom(animated: false);
    });
  }

  Future<void> _loadInitialMessages() async {
    if (_conversationId <= 0) return;
    try {
      await _markAsRead();
      final msgs = await _chatRepository.getMessages(_conversationId,
          token: _currentAnonToken);
      if (mounted) {
        setState(() {
          _messages.clear();
          _messages.addAll(msgs);
          if (_messages.isNotEmpty) {
            _lastMessageId = _messages.last.id;
          }
          _loading = false;
        });
        _afterLayoutScroll();
      }
    } catch (e) {
      if (mounted) {
        setState(() => _loading = false);
        ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Error loading messages: $e')));
      }
    }
  }

  Future<void> _markAsRead() async {
    if (_conversationId <= 0) return;
    try {
      await _chatRepository
          .markAsRead(_conversationId); // Might need token support here too
    } catch (e) {
      // Ignore
    }
  }

  void _restartPolling() {
    _timer?.cancel();
    final interval =
        _isForeground ? _foregroundPollInterval : _backgroundPollInterval;
    _timer = Timer.periodic(interval, (timer) async {
      if (_conversationId <= 0) return;
      try {
        final newMsgs = await _chatRepository.getMessagesSince(
            _conversationId, _lastMessageId,
            token: _currentAnonToken);
        if (newMsgs.isNotEmpty && mounted) {
          await _markAsRead();
          setState(() {
            _messages.addAll(newMsgs);
            _lastMessageId = _messages.last.id;
          });
          WidgetsBinding.instance.addPostFrameCallback((_) {
            _scrollToBottom(animated: true);
          });
        }
      } catch (e) {
        // Silent error
      }
    });
  }

  void _sendMessage() async {
    final text = _controller.text.trim();
    if (text.isEmpty) return;
    try {
      // Ensure recipientId is valid integer
      int? recipientId;
      final otherUserId = widget.conversation.otherUser['id'];

      if (otherUserId is int) {
        recipientId = otherUserId;
      } else if (otherUserId is String) {
        recipientId = int.tryParse(otherUserId);
      }

      if (recipientId == null) {
        ScaffoldMessenger.of(context)
            .showSnackBar(const SnackBar(content: Text('Alıcı bulunamadı.')));
        return; // Stop here if we don't know who to send to
      }

      final result = await _chatRepository.sendMessage(_conversationId, text,
          recipientId: recipientId, token: _currentAnonToken);
      _controller.clear();

      // Handle lazy session creation updates
      if (result['new_token'] != null) {
        _currentAnonToken = result['new_token'];
        // Update my user ID if provided
        if (result['visitor_id'] != null) {
          _myUserId = result['visitor_id'].toString();
        }
      }

      // Always update my user ID if server forces it (shadow user creation)
      if (result['force_user_id_update'] != null) {
        _myUserId = result['force_user_id_update'].toString();
      }

      if (_conversationId <= 0 && result['conversation_id'] != null) {
        if (mounted) {
          setState(() {
            _conversationId = int.parse(result['conversation_id'].toString());
          });
          _restartPolling();
        }
      }

      if (_conversationId > 0) {
        final newMsgs = await _chatRepository.getMessagesSince(
            _conversationId, _lastMessageId,
            token: _currentAnonToken);
        if (newMsgs.isNotEmpty && mounted) {
          setState(() {
            _messages.addAll(newMsgs);
            _lastMessageId = _messages.last.id;
          });
          WidgetsBinding.instance.addPostFrameCallback((_) {
            _scrollToBottom(animated: true);
          });
        }
      }
    } catch (e) {
      if (mounted) {
        // Handle 429 specifically
        if (e is DioException) {
          if (e.response?.statusCode == 429) {
            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                content: Text('Wait for reply before sending more.')));
          } else if (e.response?.statusCode == 403) {
            String errorMsg = 'Access denied.';
            final data = e.response?.data;
            if (data is Map && data['error'] != null) {
              errorMsg = data['error'].toString();
            }
            final isBlocked = errorMsg.toLowerCase().contains('blocked');
            if (isBlocked) {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                content: Text('You cannot send messages to this user.'),
                backgroundColor: Colors.red,
              ));
            } else {
              ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                  content: Text(
                      'Error 403: $errorMsg (URL: ${_chatRepository.lastUrl})')));
            }
          } else {
            String errorMsg = e.message ?? 'Unknown error';
            if (e.response?.data is Map) {
              if (e.response?.data['error'] != null) {
                errorMsg = e.response?.data['error'];
              }
            } else if (e.response?.data is String) {
              errorMsg = e.response?.data;
            }

            ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                content: Text(
                    'Failed: $errorMsg (Status: ${e.response?.statusCode})')));
          }
        } else {
          ScaffoldMessenger.of(context)
              .showSnackBar(SnackBar(content: Text('Failed to send: $e')));
        }
      }
    }
  }

  bool _isAnonymous(Map<String, dynamic>? user) {
    if (user == null) return false;
    final username = user['username']?.toString() ?? '';
    return username.startsWith('anon_');
  }

  int _extractPartnerId() {
    final otherUserId = widget.conversation.otherUser['id'];
    if (otherUserId is int) return otherUserId;
    if (otherUserId is String) return int.tryParse(otherUserId) ?? 0;
    return int.tryParse(otherUserId?.toString() ?? '') ?? 0;
  }

  Future<void> _loadInitialBlockStatus() async {
    if (_conversationId <= 0) return;
    if (_loadingBlockStatus) return;
    final partnerId = _extractPartnerId();
    setState(() => _loadingBlockStatus = true);
    try {
      final blocked = await _chatRepository.getBlockStatus(
        targetId: partnerId,
        conversationId: _conversationId,
        token: _currentAnonToken,
      );
      if (mounted) setState(() => _iBlockedThisUser = blocked);
    } catch (e) {
    } finally {
      if (mounted) setState(() => _loadingBlockStatus = false);
    }
  }

  Future<void> _toggleBlock() async {
    if (_conversationId <= 0) return;
    final partnerId = _extractPartnerId();

    final actionText = _iBlockedThisUser ? 'Unblock' : 'Block';
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text('$actionText User'),
        content: Text(_iBlockedThisUser
            ? 'Allow this user to message you again?'
            : 'This user will not be able to send you messages.'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(ctx, false),
              child: const Text('Cancel')),
          ElevatedButton(
              onPressed: () => Navigator.pop(ctx, true),
              child: Text(actionText)),
        ],
      ),
    );
    if (confirmed != true) return;

    try {
      final res = await _chatRepository.toggleBlock(
        targetId: partnerId,
        conversationId: _conversationId,
        token: _currentAnonToken,
      );
      final status = (res['status'] ?? '').toString();
      if (mounted) {
        setState(() {
          _iBlockedThisUser = status == 'blocked';
        });
        final msg = res['message']?.toString() ??
            (_iBlockedThisUser ? 'User blocked' : 'User unblocked');
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(msg)));
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Failed to update block: $e')));
      }
    }
  }

  Future<void> _showReportDialog() async {
    if (_conversationId <= 0) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Bu konuşma henüz hazır değil.')),
        );
      }
      return;
    }

    final partnerId = _extractPartnerId();
    const reasons = ['Spam', 'Harassment', 'Inappropriate', 'Other'];
    String selected = reasons.first;
    final otherController = TextEditingController();

    final result = await showDialog<String>(
      context: context,
      builder: (ctx) {
        return StatefulBuilder(
          builder: (ctx, setLocal) {
            return AlertDialog(
              title: const Text('Report User'),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  DropdownButtonFormField<String>(
                    value: selected,
                    items: reasons
                        .map((r) => DropdownMenuItem(value: r, child: Text(r)))
                        .toList(),
                    onChanged: (v) {
                      if (v == null) return;
                      setLocal(() {
                        selected = v;
                      });
                    },
                    decoration: const InputDecoration(
                      labelText: 'Reason',
                    ),
                  ),
                  const SizedBox(height: 12),
                  TextField(
                    controller: otherController,
                    minLines: 2,
                    maxLines: 4,
                    decoration: InputDecoration(
                      labelText: selected == 'Other'
                          ? 'Describe'
                          : 'Additional details (optional)',
                      hintText:
                          selected == 'Other' ? 'Write the reason...' : '',
                    ),
                  ),
                ],
              ),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(ctx),
                  child: const Text('Cancel'),
                ),
                ElevatedButton(
                  onPressed: () {
                    final extra = otherController.text.trim();
                    final reason = selected == 'Other'
                        ? extra
                        : (extra.isEmpty ? selected : '$selected: $extra');
                    Navigator.pop(ctx, reason.trim());
                  },
                  child: const Text('Submit'),
                ),
              ],
            );
          },
        );
      },
    );

    if (!mounted || result == null) return;
    final reason = result.trim();
    if (reason.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Reason is required.')),
      );
      return;
    }

    if (_submittingReport) return;
    setState(() => _submittingReport = true);
    try {
      await _chatRepository.createReport(
        reportedUserId: partnerId,
        conversationId: _conversationId,
        reason: reason,
        token: _currentAnonToken,
      );
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Report submitted. Thank you.')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Failed to submit report: $e')),
        );
      }
    } finally {
      if (mounted) setState(() => _submittingReport = false);
    }
  }

  Future<void> _clearChat() async {
    if (_conversationId <= 0) return;

    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Clear Chat'),
        content: const Text(
            'Delete chat history? This will only remove it from your device.'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(ctx, false),
              child: const Text('Cancel')),
          ElevatedButton(
              onPressed: () => Navigator.pop(ctx, true),
              child: const Text('Clear')),
        ],
      ),
    );
    if (confirmed != true) return;

    try {
      await _chatRepository.clearConversation(_conversationId,
          token: _currentAnonToken);
      await _chatRepository.clearConversationCache(_conversationId);
      if (!mounted) return;
      setState(() {
        _messages.clear();
        _lastMessageId = 0;
        _loading = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Chat history cleared')),
      );
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Failed to clear chat: $e')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    final other = widget.conversation.otherUser;
    final otherName = other['display_name'] ?? other['username'] ?? 'Chat';
    final otherAvatar = other['avatar_url'] as String?;
    final canOpenProfile = other['id'] != null && !_isAnonymous(other);

    return Scaffold(
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        titleSpacing: 8,
        actions: [
          PopupMenuButton<String>(
            icon: const Icon(Icons.more_vert),
            onSelected: (value) {
              if (value == 'report') _showReportDialog();
              if (value == 'block') _toggleBlock();
              if (value == 'clear') _clearChat();
            },
            itemBuilder: (context) => [
              PopupMenuItem<String>(
                value: 'block',
                child: ListTile(
                  dense: true,
                  leading:
                      Icon(_iBlockedThisUser ? Icons.lock_open : Icons.block),
                  title:
                      Text(_iBlockedThisUser ? 'Unblock User' : 'Block User'),
                ),
              ),
              PopupMenuItem<String>(
                value: 'clear',
                child: ListTile(
                  dense: true,
                  leading: Icon(Icons.delete_outline),
                  title: Text('Clear Chat'),
                ),
              ),
              PopupMenuItem<String>(
                value: 'report',
                child: ListTile(
                  dense: true,
                  leading: Icon(Icons.flag_outlined),
                  title: Text('Report User'),
                ),
              ),
            ],
          ),
        ],
        title: GestureDetector(
          onTap: canOpenProfile
              ? () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (_) => ProfileScreen(userId: other['id']),
                    ),
                  );
                }
              : null,
          child: Row(
            children: [
              _PremiumAvatar(
                  title: otherName.toString(),
                  imageUrl: otherAvatar,
                  radius: 18),
              const SizedBox(width: 10),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      otherName.toString(),
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.w800,
                        color: scheme.onSurface,
                        letterSpacing: -0.2,
                      ),
                    ),
                    Text(
                      widget.conversation.isAnonymous
                          ? 'Anon sohbet'
                          : 'Sohbet',
                      style: TextStyle(
                        fontSize: 12,
                        color: scheme.onSurfaceVariant,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
      body: Stack(
        children: [
          Positioned.fill(
            child: DecoratedBox(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                  colors: [
                    scheme.primary.withAlpha(18),
                    scheme.surface,
                    scheme.tertiary.withAlpha(14),
                  ],
                ),
              ),
            ),
          ),
          Column(
            children: [
              Expanded(
                child: (_loading && _messages.isEmpty)
                    ? const Center(child: CircularProgressIndicator())
                    : _messages.isEmpty
                        ? Center(
                            child: Text(
                              'Henüz mesaj yok.',
                              style: TextStyle(
                                  color: scheme.onSurfaceVariant,
                                  fontWeight: FontWeight.w600),
                            ),
                          )
                        : ListView.builder(
                            controller: _scrollController,
                            padding: EdgeInsets.fromLTRB(
                                12,
                                MediaQuery.of(context).padding.top + 72,
                                12,
                                18),
                            itemCount: _messages.length,
                            itemBuilder: (context, index) {
                              final msg = _messages[index];
                              final isMe = msg.senderId.toString() == _myUserId;
                              final prev =
                                  index > 0 ? _messages[index - 1] : null;
                              final next = index + 1 < _messages.length
                                  ? _messages[index + 1]
                                  : null;
                              final startsGroup =
                                  prev == null || prev.senderId != msg.senderId;
                              final endsGroup =
                                  next == null || next.senderId != msg.senderId;

                              String? labelToShow;
                              if (!isMe && startsGroup) {
                                labelToShow = msg.senderAlias ??
                                    msg.senderAnonLabel ??
                                    (other['display_name'] ?? other['username'])
                                        ?.toString();
                              }

                              return _MessageRow(
                                isMe: isMe,
                                text: msg.bodyText ?? '',
                                timeText: _formatTime(msg.createdAt),
                                showMeta: endsGroup,
                                isRead: msg.isRead,
                                label: labelToShow,
                                avatarUrl:
                                    !isMe && endsGroup ? otherAvatar : null,
                                avatarTitle: otherName.toString(),
                              );
                            },
                          ),
              ),
              SafeArea(
                top: false,
                child: _Composer(
                  controller: _controller,
                  onSend: _sendMessage,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class _PremiumAvatar extends StatelessWidget {
  final String title;
  final String? imageUrl;
  final double radius;

  const _PremiumAvatar(
      {required this.title, required this.imageUrl, required this.radius});

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    final letter = title.isNotEmpty ? title[0].toUpperCase() : '?';
    return Container(
      padding: const EdgeInsets.all(2),
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        gradient: LinearGradient(colors: [scheme.primary, scheme.tertiary]),
      ),
      child: CircleAvatar(
        radius: radius,
        backgroundColor: scheme.surface,
        foregroundColor: scheme.onSurface,
        backgroundImage: imageUrl != null ? NetworkImage(imageUrl!) : null,
        child: imageUrl == null
            ? Text(letter, style: const TextStyle(fontWeight: FontWeight.w800))
            : null,
      ),
    );
  }
}

class _MessageRow extends StatelessWidget {
  final bool isMe;
  final String text;
  final String timeText;
  final bool showMeta;
  final bool isRead;
  final String? label;
  final String? avatarUrl;
  final String avatarTitle;

  const _MessageRow({
    required this.isMe,
    required this.text,
    required this.timeText,
    required this.showMeta,
    required this.isRead,
    required this.label,
    required this.avatarUrl,
    required this.avatarTitle,
  });

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    final bubbleColor = isMe ? scheme.primary : scheme.surfaceContainerHighest;
    final textColor = isMe ? scheme.onPrimary : scheme.onSurface;

    final radius = BorderRadius.only(
      topLeft: const Radius.circular(18),
      topRight: const Radius.circular(18),
      bottomLeft: Radius.circular(isMe ? 18 : 6),
      bottomRight: Radius.circular(isMe ? 6 : 18),
    );

    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment:
            isMe ? MainAxisAlignment.end : MainAxisAlignment.start,
        children: [
          if (!isMe) ...[
            if (avatarUrl != null)
              _PremiumAvatar(
                  title: avatarTitle, imageUrl: avatarUrl, radius: 14)
            else
              const SizedBox(width: 32),
            const SizedBox(width: 8),
          ],
          Flexible(
            child: Column(
              crossAxisAlignment:
                  isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
              children: [
                if (label != null)
                  Padding(
                    padding: const EdgeInsets.only(left: 6, bottom: 4),
                    child: Text(
                      label!,
                      style: TextStyle(
                        fontSize: 12,
                        fontWeight: FontWeight.w700,
                        color: scheme.onSurfaceVariant,
                      ),
                    ),
                  ),
                Container(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
                  decoration: BoxDecoration(
                    color: bubbleColor,
                    borderRadius: radius,
                    boxShadow: [
                      BoxShadow(
                        color: scheme.shadow.withAlpha(18),
                        blurRadius: 16,
                        offset: const Offset(0, 10),
                      ),
                    ],
                  ),
                  child: Text(
                    text,
                    style: TextStyle(
                      color: textColor,
                      fontWeight: FontWeight.w600,
                      letterSpacing: -0.1,
                      height: 1.25,
                    ),
                  ),
                ),
                if (showMeta)
                  Padding(
                    padding: const EdgeInsets.only(top: 4, left: 6, right: 6),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text(
                          timeText,
                          style: TextStyle(
                              fontSize: 11,
                              color: scheme.onSurfaceVariant,
                              fontWeight: FontWeight.w600),
                        ),
                        if (isMe) ...[
                          const SizedBox(width: 6),
                          Icon(
                            isRead
                                ? Icons.done_all_rounded
                                : Icons.done_rounded,
                            size: 14,
                            color: scheme.onSurfaceVariant,
                          ),
                        ],
                      ],
                    ),
                  ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _Composer extends StatelessWidget {
  final TextEditingController controller;
  final VoidCallback onSend;

  const _Composer({required this.controller, required this.onSend});

  void _insertEmoji(String emoji) {
    final value = controller.value;
    final text = value.text;
    final selection = value.selection;
    final start = selection.start >= 0 ? selection.start : text.length;
    final end = selection.end >= 0 ? selection.end : text.length;
    final newText = text.replaceRange(start, end, emoji);
    final cursor = start + emoji.length;
    controller.value = value.copyWith(
      text: newText,
      selection: TextSelection.collapsed(offset: cursor),
      composing: TextRange.empty,
    );
  }

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    return Container(
      padding: const EdgeInsets.fromLTRB(12, 10, 12, 12),
      decoration: BoxDecoration(
        color: scheme.surface,
        border: Border(
            top: BorderSide(color: scheme.outlineVariant.withAlpha(100))),
      ),
      child: Row(
        children: [
          Expanded(
            child: Container(
              decoration: BoxDecoration(
                color: scheme.surfaceContainerHighest,
                borderRadius: BorderRadius.circular(18),
                border: Border.all(color: scheme.outlineVariant.withAlpha(110)),
              ),
              padding: const EdgeInsets.symmetric(horizontal: 12),
              child: Row(
                children: [
                  IconButton(
                    visualDensity: VisualDensity.compact,
                    padding: EdgeInsets.zero,
                    constraints:
                        const BoxConstraints(minWidth: 40, minHeight: 40),
                    icon: Icon(Icons.mood_rounded,
                        color: scheme.onSurfaceVariant),
                    onPressed: () async {
                      FocusScope.of(context).unfocus();
                      final emoji = await showModalBottomSheet<String>(
                        context: context,
                        backgroundColor: scheme.surface,
                        isScrollControlled: false,
                        shape: const RoundedRectangleBorder(
                          borderRadius:
                              BorderRadius.vertical(top: Radius.circular(24)),
                        ),
                        builder: (_) => const _EmojiPickerSheet(),
                      );
                      if (emoji != null && emoji.isNotEmpty) {
                        _insertEmoji(emoji);
                      }
                    },
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: TextField(
                      controller: controller,
                      minLines: 1,
                      maxLines: 5,
                      textInputAction: TextInputAction.newline,
                      decoration: const InputDecoration(
                        hintText: 'Mesaj yaz…',
                        border: InputBorder.none,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          const SizedBox(width: 10),
          Container(
            decoration: BoxDecoration(
              gradient:
                  LinearGradient(colors: [scheme.primary, scheme.tertiary]),
              borderRadius: BorderRadius.circular(18),
              boxShadow: [
                BoxShadow(
                  color: scheme.primary.withAlpha(38),
                  blurRadius: 18,
                  offset: const Offset(0, 10),
                ),
              ],
            ),
            child: Material(
              color: Colors.transparent,
              child: InkWell(
                borderRadius: BorderRadius.circular(18),
                onTap: onSend,
                child: SizedBox(
                  width: 48,
                  height: 48,
                  child: Icon(Icons.send_rounded,
                      color: scheme.onPrimary, size: 20),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _EmojiPickerSheet extends StatelessWidget {
  const _EmojiPickerSheet();

  static const List<String> _emojis = [
    '😀',
    '😃',
    '😄',
    '😁',
    '😅',
    '😂',
    '🙂',
    '😉',
    '😊',
    '😍',
    '😘',
    '😜',
    '🤔',
    '😎',
    '🥳',
    '😭',
    '😡',
    '👍',
    '👎',
    '🙏',
    '👏',
    '💪',
    '🎉',
    '❤️',
    '🔥',
    '💯',
    '✨',
    '😴',
    '🤝',
    '👀',
    '💔',
    '😇',
    '😬',
    '🤩',
    '😮',
    '🤗',
  ];

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    return SafeArea(
      top: false,
      child: Padding(
        padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 44,
              height: 5,
              decoration: BoxDecoration(
                color: scheme.outlineVariant.withAlpha(120),
                borderRadius: BorderRadius.circular(999),
              ),
            ),
            const SizedBox(height: 12),
            Align(
              alignment: Alignment.centerLeft,
              child: Text(
                'Emoji',
                style: TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w800,
                  color: scheme.onSurface,
                ),
              ),
            ),
            const SizedBox(height: 12),
            GridView.builder(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 8,
                mainAxisSpacing: 8,
                crossAxisSpacing: 8,
              ),
              itemCount: _emojis.length,
              itemBuilder: (context, index) {
                final emoji = _emojis[index];
                return InkWell(
                  borderRadius: BorderRadius.circular(12),
                  onTap: () => Navigator.pop(context, emoji),
                  child: Center(
                    child: Text(
                      emoji,
                      style: const TextStyle(fontSize: 22),
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}
