import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:real_estate_mobile/core/constants/app_colors.dart';
import 'package:real_estate_mobile/core/utils/image_url_resolver.dart';
import 'package:real_estate_mobile/core/widgets/s3_image.dart';
import 'package:real_estate_mobile/features/auth/presentation/providers/auth_provider.dart';
import 'package:real_estate_mobile/features/messaging/data/models/messaging_models.dart';
import 'package:real_estate_mobile/features/messaging/data/socket_service.dart';
import 'package:real_estate_mobile/features/messaging/presentation/providers/messaging_provider.dart';
import 'package:url_launcher/url_launcher.dart';

class ChatScreen extends ConsumerStatefulWidget {
  final String conversationId;

  const ChatScreen({super.key, required this.conversationId});

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

class _ChatScreenState extends ConsumerState<ChatScreen> {
  final TextEditingController _messageController = TextEditingController();
  final ScrollController _scrollController = ScrollController();
  final FocusNode _messageFocusNode = FocusNode();
  bool _isComposing = false;
  int _previousMessageCount = 0;

  final SocketService _socket = SocketService();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final notifier = ref.read(messagingProvider.notifier);
      notifier.setActiveConversation(widget.conversationId);
      notifier.loadMessages(widget.conversationId);
      notifier.markAsRead(widget.conversationId);
      // Join socket room for real-time updates (socket is connected at auth time)
      if (_socket.isConnected) {
        _socket.joinConversation(widget.conversationId);
      } else {
        // Wait for socket connection then join
        _socket.onConnectionChange.first.then((connected) {
          if (connected && mounted) {
            _socket.joinConversation(widget.conversationId);
          }
        });
      }
    });
    _scrollController.addListener(_onScroll);
    _messageController.addListener(_onTextChanged);
  }

  @override
  void dispose() {
    // Stop typing and leave room before disposing
    if (_isComposing) {
      _socket.stopTyping(widget.conversationId);
    }
    _socket.leaveConversation(widget.conversationId);
    ref.read(messagingProvider.notifier).setActiveConversation(null);
    _messageController.dispose();
    _scrollController.dispose();
    _messageFocusNode.dispose();
    super.dispose();
  }

  void _onScroll() {
    if (_scrollController.position.pixels >=
        _scrollController.position.maxScrollExtent - 50) {
      ref
          .read(messagingProvider.notifier)
          .loadMessages(widget.conversationId, loadMore: true);
    }
  }

  void _onTextChanged() {
    final composing = _messageController.text.trim().isNotEmpty;
    if (composing != _isComposing) {
      setState(() => _isComposing = composing);
      // Emit typing indicator via socket
      if (composing) {
        _socket.startTyping(widget.conversationId);
      } else {
        _socket.stopTyping(widget.conversationId);
      }
    }
  }

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

  void _sendMessage() {
    final text = _messageController.text.trim();
    if (text.isEmpty) return;

    _socket.stopTyping(widget.conversationId);
    ref
        .read(messagingProvider.notifier)
        .sendMessage(widget.conversationId, text);
    _messageController.clear();
    setState(() => _isComposing = false);

    Future.delayed(const Duration(milliseconds: 100), () {
      _scrollToBottom();
    });
  }

  void _handleBack() {
    ref.read(messagingProvider.notifier).setActiveConversation(null);
    context.go('/messages');
  }

  // ============================================================
  // DATE / TIME FORMATTING
  // ============================================================

  String _formatTime(String isoTimestamp) {
    try {
      final dt = DateTime.parse(isoTimestamp).toLocal();
      final hour = dt.hour > 12
          ? dt.hour - 12
          : (dt.hour == 0 ? 12 : dt.hour);
      final minute = dt.minute.toString().padLeft(2, '0');
      final amPm = dt.hour >= 12 ? 'PM' : 'AM';
      return '$hour:$minute $amPm';
    } catch (_) {
      return '';
    }
  }

  String _formatDateSeparator(DateTime date) {
    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);
    final messageDate = DateTime(date.year, date.month, date.day);
    final diff = today.difference(messageDate).inDays;

    if (diff == 0) return 'Today';
    if (diff == 1) return 'Yesterday';

    const months = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November', 'December',
    ];
    return '${months[date.month - 1]} ${date.day}, ${date.year}';
  }

  bool _shouldShowDateSeparator(List<ChatMessage> messages, int index) {
    if (index == messages.length - 1) return true;

    final current = DateTime.parse(messages[index].createdAt).toLocal();
    final older = DateTime.parse(messages[index + 1].createdAt).toLocal();

    return DateTime(current.year, current.month, current.day) !=
        DateTime(older.year, older.month, older.day);
  }

  String _getInitials(String name) {
    final parts = name.trim().split(RegExp(r'\s+'));
    if (parts.isEmpty) return '';
    if (parts.length == 1) return parts[0][0].toUpperCase();
    return '${parts[0][0]}${parts[1][0]}'.toUpperCase();
  }

  String _formatFileSize(int? bytes) {
    if (bytes == null || bytes == 0) return '';
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
  }

  bool _isGiphyUrl(String text) {
    final trimmed = text.trim();
    return trimmed.contains('giphy.com/') || trimmed.contains('giphy.gif');
  }

  bool _isGifUrl(String url) {
    final lower = url.trim().toLowerCase();
    return lower.endsWith('.gif') || _isGiphyUrl(url) || lower.contains('tenor.com/');
  }

  // ============================================================
  // BUILD
  // ============================================================

  @override
  Widget build(BuildContext context) {
    final messagingState = ref.watch(messagingProvider);
    final currentUserId = ref.read(authProvider).user?.id;
    final messages = messagingState.messages[widget.conversationId] ?? [];
    final isTyping = messagingState.typingUsers.isNotEmpty;

    final conversation = messagingState.conversations
        .cast<Conversation?>()
        .firstWhere(
          (c) => c!.id == widget.conversationId,
          orElse: () => null,
        );

    if (messages.length > _previousMessageCount && _previousMessageCount > 0) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        _scrollToBottom(animated: true);
      });
    }
    _previousMessageCount = messages.length;

    final otherPartyName = conversation?.otherParty.name ?? 'Chat';
    final otherPartyAvatar = conversation?.otherParty.avatar;
    final isOnline = conversation?.otherParty.isOnline ?? false;
    final otherPartyHeadline = conversation?.otherParty.headline;

    return Column(
      children: [
        // Chat header with name + status
        _buildHeader(
          name: otherPartyName,
          isOnline: isOnline,
          avatar: otherPartyAvatar,
        ),
        Expanded(
          child: messagingState.isLoadingMessages && messages.isEmpty
              ? const Center(
                  child: CircularProgressIndicator(
                    color: AppColors.accentOrange,
                    strokeWidth: 2,
                  ),
                )
              : _buildChatBody(
                  messages: messages,
                  currentUserId: currentUserId ?? '',
                  otherPartyName: otherPartyName,
                  otherPartyAvatar: otherPartyAvatar,
                  otherPartyHeadline: otherPartyHeadline,
                  isOnline: isOnline,
                  isTyping: isTyping,
                  isLoadingMore: messagingState.isLoadingMessages &&
                      messages.isNotEmpty,
                ),
        ),
        _buildInputArea(),
      ],
    );
  }

  // ============================================================
  // HEADER
  // ============================================================

  Widget _buildHeader({
    required String name,
    required bool isOnline,
    String? avatar,
  }) {
    final initials = _getInitials(name);

    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 10, 12, 6),
      child: Row(
        children: [
          // Back arrow
          GestureDetector(
            onTap: _handleBack,
            behavior: HitTestBehavior.opaque,
            child: const Padding(
              padding: EdgeInsets.only(right: 12),
              child: Icon(
                Icons.arrow_back,
                size: 22,
                color: AppColors.primaryDark,
              ),
            ),
          ),
          // Avatar
          Stack(
            children: [
              ClipOval(
                child: (avatar != null && avatar.isNotEmpty)
                    ? S3Image(
                        imageUrl: avatar,
                        width: 40,
                        height: 40,
                        fit: BoxFit.cover,
                        errorWidget: (_) =>
                            _AvatarFallback(letter: initials, size: 40),
                      )
                    : _AvatarFallback(letter: initials, size: 40),
              ),
              if (isOnline)
                Positioned(
                  right: 0,
                  bottom: 0,
                  child: Container(
                    width: 10,
                    height: 10,
                    decoration: BoxDecoration(
                      color: const Color(0xFF4CAF50),
                      shape: BoxShape.circle,
                      border: Border.all(color: Colors.white, width: 2),
                    ),
                  ),
                ),
            ],
          ),
          const SizedBox(width: 10),
          // Name and active status
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  name,
                  style: const TextStyle(
                    fontFamily: 'Fractul',
                    fontSize: 14,
                    fontWeight: FontWeight.w700,
                    color: AppColors.primaryDark,
                  ),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
                const SizedBox(height: 2),
                Row(
                  children: [
                    if (isOnline) ...[
                      Container(
                        width: 8,
                        height: 8,
                        decoration: const BoxDecoration(
                          color: Color(0xFF4CAF50),
                          shape: BoxShape.circle,
                        ),
                      ),
                      const SizedBox(width: 5),
                    ],
                    Text(
                      isOnline ? 'Active Now' : 'Offline',
                      style: const TextStyle(
                        fontFamily: 'Fractul',
                        fontSize: 10,
                        fontWeight: FontWeight.w400,
                        color: AppColors.primaryDark,
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
          // Three dots (vertical)
          GestureDetector(
            onTap: () {},
            behavior: HitTestBehavior.opaque,
            child: const Padding(
              padding: EdgeInsets.symmetric(horizontal: 10),
              child: Icon(
                Icons.more_vert,
                size: 20,
                color: AppColors.primaryDark,
              ),
            ),
          ),
          // Star icon
          GestureDetector(
            onTap: () {},
            behavior: HitTestBehavior.opaque,
            child: Padding(
              padding: const EdgeInsets.only(right: 4),
              child: Icon(
                Icons.star_rounded,
                size: 24,
                color: AppColors.accentOrange,
              ),
            ),
          ),
        ],
      ),
    );
  }

  // ============================================================
  // CHAT BODY
  // ============================================================

  Widget _buildChatBody({
    required List<ChatMessage> messages,
    required String currentUserId,
    required String otherPartyName,
    String? otherPartyAvatar,
    String? otherPartyHeadline,
    required bool isOnline,
    required bool isTyping,
    required bool isLoadingMore,
  }) {
    if (messages.isEmpty) {
      return SingleChildScrollView(
        child: Column(
          children: [
            _buildProfileSection(
              name: otherPartyName,
              avatar: otherPartyAvatar,
              headline: otherPartyHeadline,
              isOnline: isOnline,
            ),
            const SizedBox(height: 60),
            Text(
              'No messages yet.\nSay hello!',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 14,
                fontWeight: FontWeight.w400,
                color: AppColors.hintText,
              ),
            ),
          ],
        ),
      );
    }

    return _buildMessagesList(
      messages: messages,
      currentUserId: currentUserId,
      currentUserName: 'You',
      otherPartyName: otherPartyName,
      otherPartyAvatar: otherPartyAvatar,
      otherPartyHeadline: otherPartyHeadline,
      isOnline: isOnline,
      isTyping: isTyping,
      isLoadingMore: isLoadingMore,
    );
  }

  // ============================================================
  // PROFILE SECTION
  // ============================================================

  Widget _buildProfileSection({
    required String name,
    String? avatar,
    String? headline,
    required bool isOnline,
  }) {
    final initials = _getInitials(name);

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Large avatar with online dot
          Stack(
            children: [
              ClipOval(
                child: (avatar != null && avatar.isNotEmpty)
                    ? S3Image(
                        imageUrl: avatar,
                        width: 80,
                        height: 80,
                        fit: BoxFit.cover,
                        errorWidget: (_) =>
                            _AvatarFallback(letter: initials, size: 80),
                      )
                    : _AvatarFallback(letter: initials, size: 80),
              ),
              if (isOnline)
                Positioned(
                  right: 2,
                  bottom: 2,
                  child: Container(
                    width: 14,
                    height: 14,
                    decoration: BoxDecoration(
                      color: const Color(0xFF4CAF50),
                      shape: BoxShape.circle,
                      border: Border.all(color: Colors.white, width: 2.5),
                    ),
                  ),
                ),
            ],
          ),
          const SizedBox(height: 14),
          // Name with pronouns and orange dot
          Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Flexible(
                child: Text(
                  name,
                  style: const TextStyle(
                    fontFamily: 'Fractul',
                    fontSize: 14,
                    fontWeight: FontWeight.w600,
                    color: AppColors.primaryDark,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              const SizedBox(width: 6),
              const Text(
                '(He/Him)',
                style: TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 14,
                  fontWeight: FontWeight.w400,
                  color: AppColors.primaryDark,
                ),
              ),
              const SizedBox(width: 6),
              Container(
                width: 10,
                height: 10,
                decoration: const BoxDecoration(
                  color: AppColors.accentOrange,
                  shape: BoxShape.circle,
                ),
              ),
            ],
          ),
          const SizedBox(height: 12),
          // Specialties row
          if (headline != null && headline.isNotEmpty)
            _buildSpecialtiesRow(headline)
          else
            _buildSpecialtiesRow('Sales,Analytics,Inspection,Residential,Commercial'),
          const SizedBox(height: 12),
          // Divider
          Divider(
            color: AppColors.primaryDark.withValues(alpha: 0.1),
            thickness: 0.5,
          ),
        ],
      ),
    );
  }

  Widget _buildSpecialtiesRow(String headline) {
    final specialties = headline.split(RegExp(r'[,|;]'))
        .map((s) => s.trim())
        .where((s) => s.isNotEmpty)
        .toList();

    if (specialties.isEmpty) return const SizedBox.shrink();

    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Row(
        children: [
          for (int i = 0; i < specialties.length; i++) ...[
            Text(
              specialties[i],
              style: const TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 14,
                fontWeight: FontWeight.w400,
                color: AppColors.primaryDark,
              ),
            ),
            if (i < specialties.length - 1)
              const SizedBox(width: 16),
          ],
        ],
      ),
    );
  }

  // ============================================================
  // MESSAGES LIST
  // ============================================================

  Widget _buildMessagesList({
    required List<ChatMessage> messages,
    required String currentUserId,
    required String currentUserName,
    required String otherPartyName,
    String? otherPartyAvatar,
    String? otherPartyHeadline,
    required bool isOnline,
    required bool isTyping,
    required bool isLoadingMore,
  }) {
    final itemCount =
        messages.length + 1 + (isLoadingMore ? 1 : 0) + (isTyping ? 1 : 0);

    return ListView.builder(
      controller: _scrollController,
      reverse: true,
      padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
      itemCount: itemCount,
      itemBuilder: (context, index) {
        if (isTyping && index == 0) {
          return _buildTypingIndicator();
        }

        final adjustedIndex = isTyping ? index - 1 : index;

        final profileIndex = messages.length + (isLoadingMore ? 1 : 0);
        if (adjustedIndex == profileIndex) {
          return _buildProfileSection(
            name: otherPartyName,
            avatar: otherPartyAvatar,
            headline: otherPartyHeadline,
            isOnline: isOnline,
          );
        }

        if (isLoadingMore && adjustedIndex == messages.length) {
          return const Padding(
            padding: EdgeInsets.symmetric(vertical: 16),
            child: Center(
              child: SizedBox(
                width: 20,
                height: 20,
                child: CircularProgressIndicator(
                  color: AppColors.accentOrange,
                  strokeWidth: 2,
                ),
              ),
            ),
          );
        }

        if (adjustedIndex < 0 || adjustedIndex >= messages.length) {
          return const SizedBox.shrink();
        }

        final message = messages[adjustedIndex];
        final isMine = message.isMine(currentUserId);

        final showDateSeparator =
            _shouldShowDateSeparator(messages, adjustedIndex);

        final senderName = isMine
            ? (message.sender.displayName.isNotEmpty
                ? message.sender.displayName
                : currentUserName)
            : otherPartyName;
        final senderAvatar = isMine ? null : otherPartyAvatar;

        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Column(
            children: [
              if (showDateSeparator)
                _buildDateSeparator(
                  DateTime.parse(message.createdAt).toLocal(),
                ),
              Padding(
                padding: const EdgeInsets.only(bottom: 16),
                child: isMine
                    ? _buildSentMessage(message, senderName)
                    : _buildReceivedMessage(message, senderName, senderAvatar),
              ),
            ],
          ),
        );
      },
    );
  }

  // -- Date Separator --
  Widget _buildDateSeparator(DateTime date) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 16),
      child: Row(
        children: [
          Expanded(
            child: Divider(
              color: AppColors.primaryDark.withValues(alpha: 0.1),
              thickness: 0.5,
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 12),
            child: Text(
              _formatDateSeparator(date),
              style: const TextStyle(
                fontFamily: 'SourceSerif4',
                fontSize: 12,
                fontWeight: FontWeight.w400,
                color: AppColors.subtleText,
              ),
            ),
          ),
          Expanded(
            child: Divider(
              color: AppColors.primaryDark.withValues(alpha: 0.1),
              thickness: 0.5,
            ),
          ),
        ],
      ),
    );
  }

  // ============================================================
  // MESSAGE CONTENT (handles text, image, gif, file)
  // ============================================================

  Widget _buildMessageContent(ChatMessage message, {required bool isMine}) {
    switch (message.messageType) {
      case MessageType.image:
        return _buildImageContent(message, isMine: isMine);
      case MessageType.file:
        return _buildFileContent(message);
      case MessageType.system:
        return _buildSystemContent(message);
      case MessageType.text:
        // Detect Giphy URLs sent as text and render as GIF image
        if (_isGiphyUrl(message.content)) {
          return _buildImageContent(message, isMine: isMine);
        }
        return Text(
          message.content,
          style: const TextStyle(
            fontFamily: 'Fractul',
            fontSize: 10,
            fontWeight: FontWeight.w400,
            color: AppColors.primaryDark,
          ),
          textAlign: isMine ? TextAlign.right : TextAlign.left,
        );
    }
  }

  // -- Image / GIF content --
  Widget _buildImageContent(ChatMessage message, {required bool isMine}) {
    final imageUrl = message.fileUrl ?? message.content;

    // GIF from Giphy (direct URL) or S3 image
    final isDirectUrl = imageUrl.startsWith('http://') || imageUrl.startsWith('https://');
    final isGif = _isGifUrl(imageUrl) || message.mimeType == 'image/gif';

    return GestureDetector(
      onTap: () => _showImageFullScreen(context, imageUrl),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(12),
        child: ConstrainedBox(
          constraints: const BoxConstraints(
            maxWidth: 250,
            maxHeight: 250,
          ),
          child: isGif && isDirectUrl
              // Use Image.network for GIFs to preserve animation
              ? Image.network(
                  imageUrl,
                  fit: BoxFit.cover,
                  loadingBuilder: (context, child, progress) {
                    if (progress == null) return child;
                    return _buildImagePlaceholder();
                  },
                  errorBuilder: (context, error, stack) => _buildImageError(),
                )
              : isDirectUrl
                  ? CachedNetworkImage(
                      imageUrl: imageUrl,
                      fit: BoxFit.cover,
                      placeholder: (context, url) => _buildImagePlaceholder(),
                      errorWidget: (context, url, error) => _buildImageError(),
                    )
                  : S3Image(
                      imageUrl: imageUrl,
                      fit: BoxFit.cover,
                      placeholder: (_) => _buildImagePlaceholder(),
                      errorWidget: (_) => _buildImageError(),
                    ),
        ),
      ),
    );
  }

  Widget _buildImagePlaceholder() {
    return Container(
      width: 200,
      height: 150,
      color: const Color(0xFFF0F5FC),
      child: const Center(
        child: CircularProgressIndicator(
          color: AppColors.accentOrange,
          strokeWidth: 2,
        ),
      ),
    );
  }

  Widget _buildImageError() {
    return Container(
      width: 200,
      height: 150,
      color: const Color(0xFFF0F5FC),
      child: const Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.broken_image_outlined, size: 40, color: AppColors.hintText),
          SizedBox(height: 4),
          Text(
            'Image not available',
            style: TextStyle(
              fontFamily: 'SourceSerif4',
              fontSize: 12,
              color: AppColors.hintText,
            ),
          ),
        ],
      ),
    );
  }

  // -- File content --
  Widget _buildFileContent(ChatMessage message) {
    final fileName = message.fileName ?? 'File';
    final fileSize = _formatFileSize(message.fileSize);

    return GestureDetector(
      onTap: () => _openOrDownloadFile(message),
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
        decoration: BoxDecoration(
          color: const Color(0xFFF0F5FC),
          borderRadius: BorderRadius.circular(12),
          border: Border.all(
            color: AppColors.primaryDark.withValues(alpha: 0.1),
          ),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 40,
              height: 40,
              decoration: BoxDecoration(
                color: AppColors.accentOrange.withValues(alpha: 0.15),
                borderRadius: BorderRadius.circular(8),
              ),
              child: const Icon(
                Icons.attach_file,
                size: 20,
                color: AppColors.accentOrange,
              ),
            ),
            const SizedBox(width: 10),
            Flexible(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    fileName,
                    style: const TextStyle(
                      fontFamily: 'Fractul',
                      fontSize: 12,
                      fontWeight: FontWeight.w600,
                      color: AppColors.primaryDark,
                    ),
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                  ),
                  if (fileSize.isNotEmpty)
                    Text(
                      fileSize,
                      style: const TextStyle(
                        fontFamily: 'SourceSerif4',
                        fontSize: 10,
                        fontWeight: FontWeight.w400,
                        color: AppColors.hintText,
                      ),
                    ),
                ],
              ),
            ),
            const SizedBox(width: 8),
            const Icon(
              Icons.download_rounded,
              size: 20,
              color: AppColors.accentOrange,
            ),
          ],
        ),
      ),
    );
  }

  // -- System message --
  Widget _buildSystemContent(ChatMessage message) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      decoration: BoxDecoration(
        color: const Color(0xFFF0F5FC),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        message.content,
        style: const TextStyle(
          fontFamily: 'SourceSerif4',
          fontSize: 12,
          fontWeight: FontWeight.w400,
          color: AppColors.hintText,
          fontStyle: FontStyle.italic,
        ),
        textAlign: TextAlign.center,
      ),
    );
  }

  // -- Message status indicator --
  Widget _buildStatusIcon(MessageStatus status) {
    switch (status) {
      case MessageStatus.read:
        return const Icon(Icons.done_all, size: 14, color: Color(0xFF2196F3));
      case MessageStatus.delivered:
        return Icon(Icons.done_all, size: 14, color: AppColors.hintText);
      case MessageStatus.sent:
        return Icon(Icons.done, size: 14, color: AppColors.hintText);
    }
  }

  // ============================================================
  // SENT MESSAGE (right-aligned)
  // ============================================================

  Widget _buildSentMessage(ChatMessage message, String senderName) {
    final timestamp = _formatTime(message.createdAt);
    final isMediaMessage = message.messageType == MessageType.image ||
        message.messageType == MessageType.file;

    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Spacer(),
        Flexible(
          flex: 3,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              // Name row with timestamp and status
              Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  _buildStatusIcon(message.status),
                  const SizedBox(width: 4),
                  Text(
                    timestamp,
                    style: const TextStyle(
                      fontFamily: 'SourceSerif4',
                      fontSize: 10,
                      fontWeight: FontWeight.w200,
                      color: AppColors.primaryDark,
                    ),
                  ),
                  const SizedBox(width: 6),
                  Flexible(
                    child: Text(
                      senderName,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(
                        fontFamily: 'Fractul',
                        fontSize: 14,
                        fontWeight: FontWeight.w700,
                        color: AppColors.primaryDark,
                      ),
                    ),
                  ),
                  const SizedBox(width: 6),
                  Container(
                    width: 8,
                    height: 8,
                    decoration: const BoxDecoration(
                      color: AppColors.accentOrange,
                      shape: BoxShape.circle,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 6),
              // Message content
              _buildMessageContent(message, isMine: true),
              // Show text content below media if present
              if (isMediaMessage && message.content.isNotEmpty)
                Padding(
                  padding: const EdgeInsets.only(top: 4),
                  child: Text(
                    message.content,
                    style: const TextStyle(
                      fontFamily: 'Fractul',
                      fontSize: 10,
                      fontWeight: FontWeight.w400,
                      color: AppColors.primaryDark,
                    ),
                    textAlign: TextAlign.right,
                  ),
                ),
            ],
          ),
        ),
        const SizedBox(width: 10),
        // Avatar
        _buildMessageAvatar(null, senderName, 45),
      ],
    );
  }

  // ============================================================
  // RECEIVED MESSAGE (left-aligned)
  // ============================================================

  Widget _buildReceivedMessage(
      ChatMessage message, String senderName, String? avatar) {
    final timestamp = _formatTime(message.createdAt);
    final isMediaMessage = message.messageType == MessageType.image ||
        message.messageType == MessageType.file;

    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Avatar
        _buildMessageAvatar(avatar, senderName, 45),
        const SizedBox(width: 10),
        Flexible(
          flex: 3,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Name row with timestamp
              Row(
                children: [
                  Flexible(
                    child: Text(
                      senderName,
                      style: const TextStyle(
                        fontFamily: 'Fractul',
                        fontSize: 14,
                        fontWeight: FontWeight.w700,
                        color: AppColors.primaryDark,
                      ),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  const SizedBox(width: 6),
                  Container(
                    width: 8,
                    height: 8,
                    decoration: const BoxDecoration(
                      color: AppColors.accentOrange,
                      shape: BoxShape.circle,
                    ),
                  ),
                  const SizedBox(width: 6),
                  Text(
                    timestamp,
                    style: const TextStyle(
                      fontFamily: 'SourceSerif4',
                      fontSize: 10,
                      fontWeight: FontWeight.w200,
                      color: AppColors.primaryDark,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 6),
              // Message content
              _buildMessageContent(message, isMine: false),
              // Show text content below media if present
              if (isMediaMessage && message.content.isNotEmpty)
                Padding(
                  padding: const EdgeInsets.only(top: 4),
                  child: Text(
                    message.content,
                    style: const TextStyle(
                      fontFamily: 'Fractul',
                      fontSize: 10,
                      fontWeight: FontWeight.w400,
                      color: AppColors.primaryDark,
                    ),
                  ),
                ),
            ],
          ),
        ),
        const Spacer(),
      ],
    );
  }

  // -- Message Avatar --
  Widget _buildMessageAvatar(String? avatarKey, String name, double size) {
    final initials = _getInitials(name);

    return ClipOval(
      child: (avatarKey != null && avatarKey.isNotEmpty)
          ? S3Image(
              imageUrl: avatarKey,
              width: size,
              height: size,
              fit: BoxFit.cover,
              errorWidget: (_) =>
                  _AvatarFallback(letter: initials, size: size),
            )
          : _AvatarFallback(letter: initials, size: size),
    );
  }

  // -- Typing Indicator --
  Widget _buildTypingIndicator() {
    return Align(
      alignment: Alignment.centerLeft,
      child: Padding(
        padding: const EdgeInsets.only(bottom: 8),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _buildDot(0),
            const SizedBox(width: 4),
            _buildDot(1),
            const SizedBox(width: 4),
            _buildDot(2),
          ],
        ),
      ),
    );
  }

  Widget _buildDot(int index) {
    return TweenAnimationBuilder<double>(
      tween: Tween(begin: 0.3, end: 1.0),
      duration: Duration(milliseconds: 600 + (index * 200)),
      builder: (context, value, child) {
        return Opacity(
          opacity: value,
          child: Container(
            width: 6,
            height: 6,
            decoration: const BoxDecoration(
              color: AppColors.subtleText,
              shape: BoxShape.circle,
            ),
          ),
        );
      },
    );
  }

  // ============================================================
  // IMAGE FULL SCREEN VIEWER
  // ============================================================

  void _showImageFullScreen(BuildContext context, String imageUrl) {
    final isDirectUrl = imageUrl.startsWith('http://') || imageUrl.startsWith('https://');

    Navigator.of(context, rootNavigator: true).push(
      MaterialPageRoute(
        builder: (_) => Scaffold(
          backgroundColor: Colors.black,
          appBar: AppBar(
            backgroundColor: Colors.black,
            iconTheme: const IconThemeData(color: Colors.white),
            elevation: 0,
          ),
          body: Center(
            child: InteractiveViewer(
              minScale: 0.5,
              maxScale: 4.0,
              child: isDirectUrl
                  ? CachedNetworkImage(
                      imageUrl: imageUrl,
                      fit: BoxFit.contain,
                      placeholder: (context, url) => const Center(
                        child: CircularProgressIndicator(color: Colors.white),
                      ),
                      errorWidget: (context, url, error) => const Icon(
                        Icons.broken_image,
                        size: 80,
                        color: Colors.white54,
                      ),
                    )
                  : S3Image(
                      imageUrl: imageUrl,
                      fit: BoxFit.contain,
                      placeholder: (_) => const Center(
                        child: CircularProgressIndicator(color: Colors.white),
                      ),
                      errorWidget: (_) => const Icon(
                        Icons.broken_image,
                        size: 80,
                        color: Colors.white54,
                      ),
                    ),
            ),
          ),
        ),
      ),
    );
  }

  // ============================================================
  // FILE OPEN / DOWNLOAD
  // ============================================================

  Future<void> _openOrDownloadFile(ChatMessage message) async {
    final fileUrl = message.fileUrl;
    if (fileUrl == null || fileUrl.isEmpty) return;

    String? url;
    if (fileUrl.startsWith('http://') || fileUrl.startsWith('https://')) {
      url = fileUrl;
    } else {
      // Resolve S3 key to presigned download URL
      url = await ImageUrlResolver.instance.resolve(fileUrl);
    }

    if (url != null && url.isNotEmpty) {
      final uri = Uri.parse(url);
      if (await canLaunchUrl(uri)) {
        await launchUrl(uri, mode: LaunchMode.externalApplication);
      }
    }
  }

  // ============================================================
  // INPUT AREA
  // ============================================================

  Widget _buildInputArea() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
      color: Colors.white,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          // Plus icon
          GestureDetector(
            onTap: _showAttachmentOptions,
            behavior: HitTestBehavior.opaque,
            child: const Padding(
              padding: EdgeInsets.only(right: 10),
              child: Icon(
                Icons.add,
                size: 24,
                color: AppColors.primaryDark,
              ),
            ),
          ),

          // Text input pill with send icon inside
          Expanded(
            child: SizedBox(
              height: 44,
              child: TextField(
                controller: _messageController,
                focusNode: _messageFocusNode,
                textInputAction: TextInputAction.send,
                onSubmitted: (_) => _sendMessage(),
                style: const TextStyle(
                  fontFamily: 'Fractul',
                  fontSize: 14,
                  fontWeight: FontWeight.w500,
                  color: AppColors.primaryDark,
                ),
                decoration: InputDecoration(
                  hintText: 'Write a Message',
                  hintStyle: const TextStyle(
                    fontFamily: 'Fractul',
                    fontSize: 14,
                    fontWeight: FontWeight.w500,
                    color: AppColors.primaryDark,
                  ),
                  contentPadding: const EdgeInsets.symmetric(
                    horizontal: 18,
                    vertical: 12,
                  ),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(22),
                    borderSide: const BorderSide(
                      color: AppColors.primaryDark,
                      width: 1.5,
                    ),
                  ),
                  enabledBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(22),
                    borderSide: const BorderSide(
                      color: AppColors.primaryDark,
                      width: 1.5,
                    ),
                  ),
                  focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(22),
                    borderSide: const BorderSide(
                      color: AppColors.primaryDark,
                      width: 1.5,
                    ),
                  ),
                  suffixIcon: GestureDetector(
                    onTap: _sendMessage,
                    behavior: HitTestBehavior.opaque,
                    child: const Padding(
                      padding: EdgeInsets.only(right: 4),
                      child: Icon(
                        Icons.send,
                        size: 20,
                        color: AppColors.accentOrange,
                      ),
                    ),
                  ),
                  suffixIconConstraints: const BoxConstraints(
                    minWidth: 40,
                    minHeight: 20,
                  ),
                ),
              ),
            ),
          ),
          const SizedBox(width: 10),

          // Mic icon in filled dark circle
          GestureDetector(
            onTap: () => _showComingSoon('Speech to text'),
            child: Container(
              width: 36,
              height: 36,
              decoration: const BoxDecoration(
                color: AppColors.primaryDark,
                shape: BoxShape.circle,
              ),
              child: const Center(
                child: Icon(
                  Icons.mic_none,
                  size: 20,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  // ============================================================
  // HELPERS
  // ============================================================

  void _showComingSoon(String feature) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('$feature coming soon'),
        duration: const Duration(seconds: 1),
        backgroundColor: AppColors.primaryDark,
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      ),
    );
  }

  void _showAttachmentOptions() {
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.white,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      builder: (ctx) {
        return Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                width: 40,
                height: 4,
                decoration: BoxDecoration(
                  color: AppColors.divider,
                  borderRadius: BorderRadius.circular(2),
                ),
              ),
              const SizedBox(height: 20),
              _buildAttachmentOption(
                icon: Icons.image_outlined,
                label: 'Photo',
                onTap: () {
                  Navigator.pop(ctx);
                  _showComingSoon('Photo attachment');
                },
              ),
              _buildAttachmentOption(
                icon: Icons.attach_file,
                label: 'Document',
                onTap: () {
                  Navigator.pop(ctx);
                  _showComingSoon('Document attachment');
                },
              ),
              _buildAttachmentOption(
                icon: Icons.location_on_outlined,
                label: 'Location',
                onTap: () {
                  Navigator.pop(ctx);
                  _showComingSoon('Location sharing');
                },
              ),
              const SizedBox(height: 10),
            ],
          ),
        );
      },
    );
  }

  Widget _buildAttachmentOption({
    required IconData icon,
    required String label,
    required VoidCallback onTap,
  }) {
    return ListTile(
      leading: Icon(icon, color: AppColors.primaryDark),
      title: Text(
        label,
        style: const TextStyle(
          fontFamily: 'Fractul',
          fontSize: 14,
          fontWeight: FontWeight.w500,
          color: AppColors.primaryDark,
        ),
      ),
      onTap: onTap,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    );
  }

}

// -- Avatar Fallback --

class _AvatarFallback extends StatelessWidget {
  final String letter;
  final double size;

  const _AvatarFallback({required this.letter, this.size = 45});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: size,
      height: size,
      decoration: const BoxDecoration(
        color: Color(0xFFE8E8E8),
        shape: BoxShape.circle,
      ),
      alignment: Alignment.center,
      child: Text(
        letter,
        style: TextStyle(
          fontFamily: 'Fractul',
          fontSize: size * 0.38,
          fontWeight: FontWeight.w700,
          color: AppColors.primaryDark,
        ),
      ),
    );
  }
}
