// ⭐⭐⭐ UPDATED SWIPEABLE MESSAGE BUBBLE WITH IMAGE GRID VIEWER ⭐⭐⭐
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:taxglide/consts/download_helper.dart';
import 'package:taxglide/model/chat_model.dart';

class SwipeableMessageBubble extends StatefulWidget {
  final MessageModel message;
  final DateTime msgDate;
  final String Function(DateTime) formatTime;
  final Widget Function(int, int) buildTick;
  final VoidCallback onSwipe;
  final Function(int?)? onParentTagTap;
  final Function(List<String> imageUrls, int initialIndex)?
  onImageTap; // 🖼️ NEW

  const SwipeableMessageBubble({
    super.key,
    required this.message,
    required this.msgDate,
    required this.formatTime,
    required this.buildTick,
    required this.onSwipe,
    this.onParentTagTap,
    this.onImageTap, // 🖼️ NEW
  });

  @override
  State<SwipeableMessageBubble> createState() => SwipeableMessageBubbleState();
}

class SwipeableMessageBubbleState extends State<SwipeableMessageBubble>
    with SingleTickerProviderStateMixin {
  double _dragExtent = 0;
  late AnimationController _controller;
  late Animation<double> _animation;
  final Map<String, bool> _downloadingFiles = {};
  final Map<String, bool> _downloadedFiles = {};
  bool _isHighlighted = false;

  void highlight() {
    if (!mounted) return;
    // Reset first to ensure it re-triggers if already highlighted
    setState(() => _isHighlighted = false);
    
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) return;
      setState(() => _isHighlighted = true);
      Future.delayed(const Duration(milliseconds: 1500), () {
        if (mounted) setState(() => _isHighlighted = false);
      });
    });
  }

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    _animation = Tween<double>(begin: 0, end: 0).animate(_controller)
      ..addListener(() {
        setState(() {
          _dragExtent = _animation.value;
        });
      });

    _checkDownloadedFiles();
  }

  Future<void> _checkDownloadedFiles() async {
    for (var doc in widget.message.uploadedDocuments) {
      final existingPath = await DownloadHelper.checkFileExistsInReceived(
        doc.filePath,
      );
      if (existingPath != null && mounted) {
        setState(() {
          _downloadedFiles[doc.fileName] = true;
        });
      }
    }
  }

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

  void _handleDragUpdate(DragUpdateDetails details) {
    if (!mounted) return;

    final isUserMessage = widget.message.chatBy == "user";
    final delta = details.primaryDelta ?? 0;

    if ((isUserMessage && delta < 0) || (!isUserMessage && delta > 0)) {
      setState(() {
        _dragExtent += delta;
        _dragExtent = _dragExtent.clamp(
          isUserMessage ? -80.0 : 0.0,
          isUserMessage ? 0.0 : 80.0,
        );
      });
    }
  }

  void _handleDragEnd(DragEndDetails details) {
    if (!mounted) return;

    final threshold = 60.0;

    if (_dragExtent.abs() > threshold) {
      widget.onSwipe();
    }

    _animation = Tween<double>(
      begin: _dragExtent,
      end: 0,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut));

    _controller.reset();
    _controller.forward();
  }

  // 🖼️ NEW: Handle image tap - open grid viewer
  void _handleImageTap(int tappedIndex) {
    if (widget.onImageTap == null) return;

    // Get all image URLs from uploaded documents
    final imageUrls = widget.message.uploadedDocuments
        .where((doc) => DownloadHelper.isImageFile(doc.fileName))
        .map((doc) => doc.filePath)
        .toList();

    if (imageUrls.isNotEmpty) {
      widget.onImageTap!(imageUrls, tappedIndex);
    }
  }

  Future<void> _handleFileView(String url, String fileName) async {
    if (!mounted) return;

    try {
      print("👁️ Opening file: $fileName");

      final existingPath = await DownloadHelper.checkFileExistsInReceived(url);

      if (existingPath != null) {
        await DownloadHelper.openDownloadedFile(existingPath);
      } else {
        final sendFolder = await DownloadHelper.getSendFolder();
        final localPath = '${sendFolder.path}/$fileName';
        final file = File(localPath);

        if (await file.exists()) {
          await DownloadHelper.openDownloadedFile(localPath);
        } else {
          if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text("File not found locally"),
                backgroundColor: Colors.orange,
                duration: Duration(seconds: 2),
              ),
            );
          }
        }
      }
    } catch (e) {
      print("❌ View error: $e");
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text("Could not open file: $e"),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  Future<void> _handleFileDownload(String url, String fileName) async {
    if (!mounted) return;

    setState(() {
      _downloadingFiles[fileName] = true;
    });

    try {
      print("🔗 Downloading from: $url");
      final result = await DownloadHelper.downloadFileToReceived(url);

      if (!mounted) return;

      if (result['success'] == true) {
        setState(() {
          _downloadedFiles[fileName] = true;
        });

        if (mounted) {
          if (result['isNewDownload'] == false) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text("Opening $fileName"),
                backgroundColor: Colors.green,
                duration: const Duration(seconds: 1),
              ),
            );
          } else {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text("Downloaded $fileName"),
                backgroundColor: Colors.green,
                duration: const Duration(seconds: 1),
              ),
            );
          }
        }
      }
    } catch (e) {
      print("❌ Download error: $e");
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text("Download failed: $e"),
            backgroundColor: Colors.red,
          ),
        );
      }
    } finally {
      if (mounted) {
        setState(() {
          _downloadingFiles[fileName] = false;
        });
      }
    }
  }

  Future<void> _handleDownloadedFileView(String url, String fileName) async {
    if (!mounted) return;

    try {
      final existingPath = await DownloadHelper.checkFileExistsInReceived(url);
      if (existingPath != null) {
        await DownloadHelper.openDownloadedFile(existingPath);
      }
    } catch (e) {
      print("❌ View error: $e");
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text("Could not open file: $e"),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final isUserMessage = widget.message.chatBy == "user";
    final hasDocuments = widget.message.uploadedDocuments.isNotEmpty;

    print("💬 Building message bubble:");
    print("   - ID: ${widget.message.id}");
    print("   - chatBy: ${widget.message.chatBy}");
    print(
      "   - uploadedDocuments count: ${widget.message.uploadedDocuments.length}",
    );

    return Stack(
      children: [
        if (_dragExtent.abs() > 10)
          Positioned(
            right: isUserMessage ? 20 : null,
            left: isUserMessage ? null : 20,
            top: 0,
            bottom: 0,
            child: Center(
              child: Icon(
                Icons.reply_rounded,
                color: Colors.grey[600],
                size: 24,
              ),
            ),
          ),
        GestureDetector(
          onHorizontalDragUpdate: _handleDragUpdate,
          onHorizontalDragEnd: _handleDragEnd,
          child: Transform.translate(
            offset: Offset(_dragExtent, 0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                if (widget.message.user != null)
                  Padding(
                    padding: const EdgeInsets.only(left: 5, right: 5),
                    child: Align(
                      alignment: isUserMessage
                          ? Alignment.centerRight
                          : Alignment.centerLeft,
                      child: Text(
                        widget.message.user!.name,
                        style: const TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.w600,
                          color: Colors.black87,
                        ),
                      ),
                    ),
                  ),
                if (widget.message.parentTag != null)
                  GestureDetector(
                    onTap: () {
                      if (widget.onParentTagTap != null) {
                        widget.onParentTagTap!(
                          widget.message.parentTag?.id ?? widget.message.tagId,
                        );
                      }
                    },
                    child: Align(
                      alignment: isUserMessage
                          ? Alignment.centerRight
                          : Alignment.centerLeft,
                      child: Container(
                        margin: const EdgeInsets.only(
                          bottom: 4,
                          left: 5,
                          right: 5,
                        ),
                        padding: const EdgeInsets.symmetric(
                          horizontal: 10,
                          vertical: 6,
                        ),
                        constraints: BoxConstraints(
                          maxWidth: MediaQuery.of(context).size.width * 0.60,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.black.withOpacity(0.05),
                          borderRadius: BorderRadius.circular(8),
                          border: Border.all(
                            color: const Color(0xFF630A73).withOpacity(0.3),
                          ),
                        ),
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Container(
                              width: 3,
                              height: 30,
                              decoration: BoxDecoration(
                                color: const Color(0xFF630A73),
                                borderRadius: BorderRadius.circular(2),
                              ),
                            ),
                            const SizedBox(width: 8),
                            Flexible(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  if (widget.message.parentTag!.type == "file")
                                    Row(
                                      children: [
                                        Icon(
                                          Icons.insert_drive_file,
                                          size: 14,
                                          color: Colors.grey[600],
                                        ),
                                        const SizedBox(width: 4),
                                        Expanded(
                                          child: Text(
                                            widget
                                                    .message
                                                    .parentTag!
                                                    .fileName ??
                                                "File",
                                            maxLines: 1,
                                            overflow: TextOverflow.ellipsis,
                                            style: TextStyle(
                                              fontSize: 11,
                                              fontWeight: FontWeight.w600,
                                              color: Colors.grey[700],
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  Text(
                                    widget.message.parentTag!.message,
                                    maxLines: 2,
                                    overflow: TextOverflow.ellipsis,
                                    style: TextStyle(
                                      fontSize: 12,
                                      color: Colors.grey[700],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                Align(
                  alignment: isUserMessage
                      ? Alignment.centerRight
                      : Alignment.centerLeft,
                  child: ConstrainedBox(
                    constraints: BoxConstraints(
                      maxWidth: MediaQuery.of(context).size.width * 0.70,
                    ),
                    child: Container(
                      margin: const EdgeInsets.symmetric(vertical: 6),
                      padding: const EdgeInsets.symmetric(
                        vertical: 10,
                        horizontal: 14,
                      ),
                      decoration: BoxDecoration(
                        color: _isHighlighted
                            ? Colors.green.withOpacity(0.2)
                            : (isUserMessage
                                ? const Color(0xFFFFF8E2)
                                : Colors.white),
                        border: Border.all(
                          color: _isHighlighted
                              ? Colors.green.withOpacity(0.5)
                              : (isUserMessage
                                  ? const Color(0xFFF9D9C8)
                                  : const Color(0xFFE2E2E2)),
                        ),
                        borderRadius: BorderRadius.circular(10),
                        boxShadow: isUserMessage
                            ? []
                            : const [
                                BoxShadow(
                                  color: Color(0x40979797),
                                  blurRadius: 3.6,
                                  offset: Offset(0, 1),
                                ),
                              ],
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          // ⭐⭐⭐ DISPLAY uploadedDocuments WITH IMAGE GRID SUPPORT
                          if (hasDocuments)
                            ...widget.message.uploadedDocuments.asMap().entries.map((
                              entry,
                            ) {
                              final index = entry.key;
                              final doc = entry.value;
                              final isImage = DownloadHelper.isImageFile(
                                doc.fileName,
                              );
                              final isDownloading =
                                  _downloadingFiles[doc.fileName] ?? false;
                              final isDownloaded =
                                  _downloadedFiles[doc.fileName] ?? false;

                              // 🖼️ Calculate image index (only count images before this one)
                              final imageIndex = widget
                                  .message
                                  .uploadedDocuments
                                  .sublist(0, index)
                                  .where(
                                    (d) =>
                                        DownloadHelper.isImageFile(d.fileName),
                                  )
                                  .length;

                              return GestureDetector(
                                onTap: isImage
                                    ? () =>
                                          _handleImageTap(
                                            imageIndex,
                                          ) // 🖼️ Open grid viewer
                                    : (isUserMessage
                                          ? () => _handleFileView(
                                              doc.filePath,
                                              doc.fileName,
                                            )
                                          : null),
                                child: Container(
                                  margin: const EdgeInsets.only(bottom: 8),
                                  child: isImage
                                      ? Stack(
                                          children: [
                                            ClipRRect(
                                              borderRadius:
                                                  BorderRadius.circular(8),
                                              child: Image.network(
                                                doc.filePath,
                                                width: 150,
                                                height: 100,
                                                fit: BoxFit.cover,
                                                errorBuilder:
                                                    (context, error, stack) {
                                                      return Container(
                                                        width: 200,
                                                        height: 150,
                                                        color: Colors.grey[300],
                                                        child: const Center(
                                                          child: Icon(
                                                            Icons.broken_image,
                                                          ),
                                                        ),
                                                      );
                                                    },
                                              ),
                                            ),
                                            // ⭐ Download/View icon for receiver messages
                                            if (!isUserMessage)
                                              Positioned(
                                                top: 8,
                                                right: 8,
                                                child: GestureDetector(
                                                  onTap: isDownloading
                                                      ? null
                                                      : isDownloaded
                                                      ? () =>
                                                            _handleDownloadedFileView(
                                                              doc.filePath,
                                                              doc.fileName,
                                                            )
                                                      : () =>
                                                            _handleFileDownload(
                                                              doc.filePath,
                                                              doc.fileName,
                                                            ),
                                                  child: Container(
                                                    padding:
                                                        const EdgeInsets.all(8),
                                                    decoration: BoxDecoration(
                                                      color: Colors.black
                                                          .withOpacity(0.6),
                                                      shape: BoxShape.circle,
                                                    ),
                                                    child: isDownloading
                                                        ? const SizedBox(
                                                            width: 16,
                                                            height: 16,
                                                            child: CircularProgressIndicator(
                                                              strokeWidth: 2,
                                                              valueColor:
                                                                  AlwaysStoppedAnimation<
                                                                    Color
                                                                  >(
                                                                    Colors
                                                                        .white,
                                                                  ),
                                                            ),
                                                          )
                                                        : Icon(
                                                            isDownloaded
                                                                ? Icons
                                                                      .visibility
                                                                : Icons
                                                                      .download,
                                                            color: Colors.white,
                                                            size: 20,
                                                          ),
                                                  ),
                                                ),
                                              ),
                                          ],
                                        )
                                      : Container(
                                          padding: const EdgeInsets.all(10),
                                          decoration: BoxDecoration(
                                            color: Colors.grey[100],
                                            borderRadius: BorderRadius.circular(
                                              8,
                                            ),
                                            border: Border.all(
                                              color: Colors.grey[300]!,
                                            ),
                                          ),
                                          child: Row(
                                            children: [
                                              Icon(
                                                Icons.insert_drive_file,
                                                color: Colors.grey[600],
                                              ),
                                              const SizedBox(width: 8),
                                              Expanded(
                                                child: Column(
                                                  crossAxisAlignment:
                                                      CrossAxisAlignment.start,
                                                  children: [
                                                    Text(
                                                      doc.fileName,
                                                      style: const TextStyle(
                                                        fontSize: 13,
                                                        fontWeight:
                                                            FontWeight.w600,
                                                      ),
                                                    ),
                                                    Text(
                                                      doc.fileType
                                                          .toUpperCase(),
                                                      style: TextStyle(
                                                        fontSize: 11,
                                                        color: Colors.grey[600],
                                                      ),
                                                    ),
                                                  ],
                                                ),
                                              ),
                                              GestureDetector(
                                                onTap: isDownloading
                                                    ? null
                                                    : () => isUserMessage
                                                          ? _handleFileView(
                                                              doc.filePath,
                                                              doc.fileName,
                                                            )
                                                          : isDownloaded
                                                          ? _handleDownloadedFileView(
                                                              doc.filePath,
                                                              doc.fileName,
                                                            )
                                                          : _handleFileDownload(
                                                              doc.filePath,
                                                              doc.fileName,
                                                            ),
                                                child: isDownloading
                                                    ? const SizedBox(
                                                        width: 20,
                                                        height: 20,
                                                        child:
                                                            CircularProgressIndicator(
                                                              strokeWidth: 2,
                                                            ),
                                                      )
                                                    : Icon(
                                                        isUserMessage
                                                            ? Icons.open_in_new
                                                            : isDownloaded
                                                            ? Icons.visibility
                                                            : Icons.download,
                                                        color: Colors.grey[600],
                                                        size: 20,
                                                      ),
                                              ),
                                            ],
                                          ),
                                        ),
                                ),
                              );
                            }).toList(),
                          if (widget.message.message.isNotEmpty)
                            Text(
                              widget.message.message,
                              style: const TextStyle(fontSize: 15),
                            ),
                          const SizedBox(height: 3),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: [
                              Text(
                                widget.formatTime(widget.msgDate),
                                style: TextStyle(
                                  fontSize: 11,
                                  color: Colors.grey[700],
                                ),
                              ),
                              const SizedBox(width: 4),
                              widget.buildTick(
                                widget.message.isDelivered,
                                widget.message.isRead,
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}
