import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_riverpod/legacy.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:taxglide/consts/app_asstes.dart';
import 'package:taxglide/consts/app_style.dart';
import 'package:taxglide/controller/api_contoller.dart';
import 'package:taxglide/model/chat_model.dart';
import 'package:taxglide/view/Mahi_chat/chat_profile_screen.dart';
import 'package:taxglide/view/Mahi_chat/file_images_screen.dart';
import 'package:taxglide/view/Mahi_chat/webscoket.dart';

// ⭐ Provider to hold the tagged message
final taggedMessageProvider = StateProvider<MessageModel?>((ref) => null);

// ⭐ Global key map to track message positions (if you want from outside)
final messageKeysProvider = StateProvider<Map<int, GlobalKey>>((ref) => {});

class CompletedLiveChatScreen extends ConsumerStatefulWidget {
  final int chatid;
  final String? fileid;
  const CompletedLiveChatScreen({
    super.key,
    required this.chatid,
    required this.fileid,
  });

  @override
  ConsumerState<CompletedLiveChatScreen> createState() =>
      _CompletedLiveChatScreenState();
}

class _CompletedLiveChatScreenState
    extends ConsumerState<CompletedLiveChatScreen>
    with AutomaticKeepAliveClientMixin, WidgetsBindingObserver {
  bool get wantKeepAlive => true;

  final ScrollController scrollController = ScrollController();
  final ChatWebSocketService _wsService = ChatWebSocketService();

  bool showScrollButton = false;
  bool userIsReading = false;
  bool _isInitialLoad = true;
  bool _isPaginationLoading = false;
  bool _hasNewMessage = false;

  // For reply scroll - FIXED: Use unique key per message
  final Map<String, GlobalKey> _messageKeys = {};

  // ⭐⭐⭐ Key variables for smooth pagination
  final double _paginationTriggerOffset = 300; // Start loading 300px before top

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addObserver(this);

    _initializeWebSocket();

    scrollController.addListener(_handleScroll);
  }

  // ⭐⭐⭐ Enhanced scroll handler with early pagination trigger
  void _handleScroll() {
    if (!scrollController.hasClients) return;

    double position = scrollController.position.pixels;
    double bottom = scrollController.position.maxScrollExtent;
    double top = scrollController.position.minScrollExtent;

    // ⭐⭐⭐ EARLY PAGINATION: Load before reaching exact top
    if (position <= top + _paginationTriggerOffset && !_isPaginationLoading) {
      _triggerPagination();
    }

    // Show scroll to bottom button
    if (position < bottom - 50) {
      if (!userIsReading) {
        setState(() {
          userIsReading = true;
          showScrollButton = true;
        });
      }
    } else {
      if (userIsReading) {
        setState(() {
          userIsReading = false;
          showScrollButton = false;
        });
      }
    }
  }

  // ⭐⭐⭐ Smooth pagination with scroll position preservation (NO JUMP TO BOTTOM)
  Future<void> _triggerPagination() async {
    final notifier = ref.read(chatMessagesProvider(widget.chatid).notifier);
    if (!notifier.hasNextPage) return;
    if (_isPaginationLoading) return;
    if (!scrollController.hasClients) return;

    setState(() {
      _isPaginationLoading = true;
      // userIsReading remains true while scrolling old messages
    });

    // Save current scroll metrics BEFORE loading more messages
    final double beforeMaxExtent = scrollController.position.maxScrollExtent;
    final double currentOffset = scrollController.position.pixels;

    try {
      await notifier.loadMessages(); // This should prepend older messages

      // Restore scroll position after new messages loaded
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (!mounted || !scrollController.hasClients) return;

        final double afterMaxExtent = scrollController.position.maxScrollExtent;
        final double diff = afterMaxExtent - beforeMaxExtent;

        // Keep user at same visual message position
        final double newOffset = currentOffset + diff;

        scrollController.jumpTo(
          newOffset.clamp(
            scrollController.position.minScrollExtent,
            scrollController.position.maxScrollExtent,
          ),
        );

        if (mounted) {
          setState(() {
            _isPaginationLoading = false;
          });
        }
      });
    } catch (e) {
      debugPrint("❌ Pagination error: $e");
      if (mounted) {
        setState(() {
          _isPaginationLoading = false;
        });
      }
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);

    debugPrint("📱 App Lifecycle State: $state");

    if (state == AppLifecycleState.resumed) {
      debugPrint("🔄 App resumed - checking for new messages");

      if (_hasNewMessage) {
        _silentRefresh();
        _hasNewMessage = false;
      }
    }
  }

  Future<void> _silentRefresh() async {
    try {
      debugPrint("🔄 Starting silent refresh...");

      await ref.read(chatMessagesProvider(widget.chatid).notifier).refresh();

      debugPrint("✅ Silent refresh completed");

      // Only auto-scroll to bottom on new messages if user is NOT reading old ones
      if (!userIsReading && mounted) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (scrollController.hasClients) {
            scrollController.animateTo(
              scrollController.position.maxScrollExtent,
              duration: const Duration(milliseconds: 300),
              curve: Curves.easeOut,
            );
          }
        });
      }
    } catch (e) {
      debugPrint("❌ Error during silent refresh: $e");
    }
  }

  Future<void> _initializeWebSocket() async {
    try {
      _wsService.onMessageReceived = (Map<String, dynamic> message) async {
        debugPrint("📨 WebSocket message received: $message");

        try {
          final event = message['event'] as String?;

          if (event == 'message.sent' || 
              event == 'message.received' || 
              event == 'message.read' || 
              event == 'message.delivered') {
            debugPrint("🔔 Message status/new message event: $event");

            if (WidgetsBinding.instance.lifecycleState ==
                AppLifecycleState.resumed) {
              debugPrint("✅ Screen active - refreshing now");
              await _silentRefresh();
            } else {
              debugPrint("⏳ Screen not active - will refresh on resume");
              _hasNewMessage = true;
            }
          }
        } catch (e) {
          debugPrint("❌ Error handling WebSocket message: $e");
        }
      };

      _wsService.onConnected = () {
        debugPrint("✅ WebSocket Connected");
      };

      _wsService.onDisconnected = () {
        debugPrint("🔌 WebSocket Disconnected");
      };

      _wsService.onError = (error) {
        debugPrint("❌ WebSocket Error: $error");
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text("Connection error: $error"),
              backgroundColor: Colors.red,
              duration: const Duration(seconds: 2),
            ),
          );
        }
      };

      await _wsService.connect(chatId: widget.chatid.toString());
    } catch (e) {
      debugPrint("❌ Error initializing WebSocket: $e");
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _wsService.disconnect();
    scrollController.dispose();
    super.dispose();
  }

  void scrollToBottom({bool animated = false}) {
    if (!scrollController.hasClients) return;

    setState(() {
      _isPaginationLoading = false;
      userIsReading = false;
    });

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!scrollController.hasClients) return;

      if (animated) {
        scrollController
            .animateTo(
              scrollController.position.maxScrollExtent,
              duration: const Duration(milliseconds: 400),
              curve: Curves.easeOutCubic,
            )
            .then((_) {
              Future.delayed(const Duration(milliseconds: 50), () {
                if (scrollController.hasClients && mounted) {
                  scrollController.jumpTo(
                    scrollController.position.maxScrollExtent,
                  );
                }
              });
            });
      } else {
        scrollController.jumpTo(scrollController.position.maxScrollExtent);

        Future.delayed(const Duration(milliseconds: 10), () {
          if (scrollController.hasClients && mounted) {
            scrollController.jumpTo(scrollController.position.maxScrollExtent);
          }
        });
      }
    });
  }

  // ⭐ FIXED: Use unique string key instead of int
  void scrollToMessage(String messageKey) {
    final key = _messageKeys[messageKey];

    if (key != null && key.currentContext != null) {
      Scrollable.ensureVisible(
        key.currentContext!,
        duration: const Duration(milliseconds: 500),
        curve: Curves.easeInOut,
        alignment: 0.3,
      );
    }
  }

  // ⭐ FIXED: Generate unique string key for each message
  GlobalKey _getKeyForMessage(String messageKey) {
    if (!_messageKeys.containsKey(messageKey)) {
      _messageKeys[messageKey] = GlobalKey();
    }
    return _messageKeys[messageKey]!;
  }

  // ⭐ FIXED: Generate unique key string from message
  String _getMessageKeyString(MessageModel msg, int index) {
    // Use combination of ID, index, and document count for uniqueness
    final id = msg.id;
    final docCount = msg.uploadedDocuments.length;
    final createdAt = msg.createdAt ?? '';
    return 'msg_${id}_${index}_${docCount}_$createdAt';
  }

  String formatMessageDate(DateTime date) {
    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);
    final msgDay = DateTime(date.year, date.month, date.day);

    if (msgDay == today) return "Today";
    if (msgDay == today.subtract(const Duration(days: 1))) return "Yesterday";
    return "${date.day}-${date.month}-${date.year}";
  }

  String formatTime(DateTime time) {
    final hour = time.hour % 12 == 0 ? 12 : time.hour % 12;
    final minute = time.minute.toString().padLeft(2, '0');
    final period = time.hour >= 12 ? "PM" : "AM";
    return "$hour:$minute $period";
  }

  Widget buildTick(MessageModel message) {
    // ⭐ Status 0/1
    final isRead = message.isRead;
    final isDelivered = message.isDelivered;

    if (isRead == 1) {
      return const Icon(Icons.done_all, size: 16, color: Colors.blue);
    } else if (isDelivered == 1) {
      return const Icon(Icons.done_all, size: 16, color: Colors.grey);
    } else {
      return const Icon(Icons.check, size: 16, color: Colors.grey);
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    final chatAsync = ref.watch(chatMessagesProvider(widget.chatid));
    final taggedMessage = ref.watch(taggedMessageProvider);

    return Scaffold(
      appBar: AppBar(
        title: Text(
          (widget.fileid != null &&
                  widget.fileid.toString().isNotEmpty &&
                  widget.fileid.toString() != "0")
              ? 'File ID : ${widget.fileid.toString()}'
              : "Live Chat",
          style: AppTextStyles.semiBold.copyWith(
            fontSize: 16,
            color: Colors.black,
          ),
        ),
        backgroundColor: Colors.white,
        elevation: 1,
        foregroundColor: Colors.black,
        centerTitle: true,

        actions: [
          Padding(
            padding: const EdgeInsets.only(right: 12), // ✅ Right end spacing
            child: GestureDetector(
              onTap: () {
                Get.to(ChatProfileScreen(chatid: widget.chatid));
              },
              child: Container(
                width: 37.446807861328125,
                height: 40,
                decoration: BoxDecoration(
                  color: const Color(0xFFFAFAFA),
                  borderRadius: BorderRadius.circular(6.81),
                  border: Border.all(
                    color: const Color(0xFF1E780C),
                    width: 0.85,
                  ),
                ),
                child: const Icon(Icons.person, color: Color(0xFF1E780C)),
              ),
            ),
          ),
        ],
      ),

      body: Stack(
        children: [
          Container(
            decoration: const BoxDecoration(
              image: DecorationImage(
                image: AssetImage(AppAssets.backgroundimages),
                fit: BoxFit.cover,
              ),
            ),
          ),
          Column(
            children: [
              Expanded(
                child: chatAsync.when(
                  loading: () => const Center(child: SizedBox.shrink()),
                  error: (e, _) => Center(child: Text(e.toString())),
                  data: (messages) {
                    // ✅ Only first load scrolls to bottom, NOT during pagination / scroll up
                    if (_isInitialLoad && !_isPaginationLoading) {
                      WidgetsBinding.instance.addPostFrameCallback((_) {
                        if (scrollController.hasClients && mounted) {
                          scrollController.jumpTo(
                            scrollController.position.maxScrollExtent,
                          );
                        }
                      });
                      _isInitialLoad = false;
                    }

                    return Stack(
                      children: [
                        ListView.builder(
                          controller: scrollController,
                          physics: const ClampingScrollPhysics(),
                          padding: const EdgeInsets.only(
                            left: 15,
                            right: 15,
                            top: 15,
                            bottom: 15,
                          ),
                          itemCount: messages.length,
                          itemBuilder: (context, index) {
                            final msg = messages[index];
                            final msgDate = DateTime.parse(msg.createdAt!);

                            final showDateHeader =
                                index == 0 ||
                                formatMessageDate(
                                      DateTime.parse(
                                        messages[index - 1].createdAt!,
                                      ),
                                    ) !=
                                    formatMessageDate(msgDate);

                            // ⭐ FIXED: Generate unique key string
                            final messageKeyString = _getMessageKeyString(
                              msg,
                              index,
                            );

                            return Column(
                              key: _getKeyForMessage(messageKeyString),
                              crossAxisAlignment: CrossAxisAlignment.stretch,
                              children: [
                                if (showDateHeader)
                                  Padding(
                                    padding: const EdgeInsets.symmetric(
                                      vertical: 10,
                                    ),
                                    child: Center(
                                      child: Container(
                                        padding: const EdgeInsets.symmetric(
                                          horizontal: 12,
                                          vertical: 5,
                                        ),
                                        decoration: BoxDecoration(
                                          color: Colors.black.withOpacity(0.06),
                                          borderRadius: BorderRadius.circular(
                                            12,
                                          ),
                                        ),
                                        child: Text(
                                          formatMessageDate(msgDate),
                                          style: const TextStyle(
                                            fontSize: 13,
                                            fontWeight: FontWeight.w600,
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                SwipeableMessageBubble(
                                  message: msg,
                                  msgDate: msgDate,
                                  formatTime: formatTime,
                                  buildTick: buildTick,
                                  onSwipe: () {
                                    ref
                                            .read(
                                              taggedMessageProvider.notifier,
                                            )
                                            .state =
                                        msg;
                                  },
                                  onParentTagTap: (tagId) {
                                    if (tagId != null) {
                                      // ⭐ FIXED: Find the message key string for the tagId
                                      final tagIndex = messages.indexWhere(
                                        (m) => m.id == tagId,
                                      );
                                      if (tagIndex != -1) {
                                        final taggedMsg = messages[tagIndex];
                                        final tagKeyString =
                                            _getMessageKeyString(
                                              taggedMsg,
                                              tagIndex,
                                            );
                                        scrollToMessage(tagKeyString);
                                      }
                                    }
                                  },
                                  // ⭐ FIXED: Use messageKeyString as ValueKey
                                  key: ValueKey(messageKeyString),
                                ),
                              ],
                            );
                          },
                        ),
                        // ⭐⭐⭐ Subtle loading indicator at top
                        if (_isPaginationLoading)
                          Positioned(
                            top: 5,
                            left: 0,
                            right: 0,
                            child: Center(
                              child: Container(
                                padding: const EdgeInsets.symmetric(
                                  horizontal: 12,
                                  vertical: 6,
                                ),
                                decoration: BoxDecoration(
                                  color: Colors.white.withOpacity(0.9),
                                  borderRadius: BorderRadius.circular(20),
                                  boxShadow: [
                                    BoxShadow(
                                      color: Colors.black.withOpacity(0.1),
                                      blurRadius: 4,
                                    ),
                                  ],
                                ),
                                child: Row(
                                  mainAxisSize: MainAxisSize.min,
                                  children: const [
                                    SizedBox(
                                      width: 14,
                                      height: 14,
                                      child: CircularProgressIndicator(
                                        strokeWidth: 2,
                                      ),
                                    ),
                                    SizedBox(width: 8),
                                    Text(
                                      "Loading...",
                                      style: TextStyle(
                                        fontSize: 12,
                                        fontWeight: FontWeight.w500,
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                      ],
                    );
                  },
                ),
              ),
              if (taggedMessage != null)
                GestureDetector(
                  onTap: () {
                    if (taggedMessage != null) {
                      // ⭐ FIXED: Need to find the message in the list to get proper key
                      final chatAsync = ref.read(
                        chatMessagesProvider(widget.chatid),
                      );
                      chatAsync.whenData((messages) {
                        final tagIndex = messages.indexWhere(
                          (m) => m.id == taggedMessage.id,
                        );
                        if (tagIndex != -1) {
                          final tagKeyString = _getMessageKeyString(
                            taggedMessage,
                            tagIndex,
                          );
                          scrollToMessage(tagKeyString);
                        }
                      });
                    }
                  },
                  child: Container(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 15,
                      vertical: 8,
                    ),
                    decoration: BoxDecoration(
                      color: Colors.grey[200],
                      border: Border(top: BorderSide(color: Colors.grey[300]!)),
                    ),
                    child: Row(
                      children: [
                        Container(
                          width: 4,
                          height: 50,
                          decoration: BoxDecoration(
                            color: const Color(0xFF630A73),
                            borderRadius: BorderRadius.circular(2),
                          ),
                        ),
                        const SizedBox(width: 10),
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                taggedMessage.user?.name ?? "Unknown",
                                style: const TextStyle(
                                  fontWeight: FontWeight.w600,
                                  fontSize: 13,
                                  color: Color(0xFF630A73),
                                ),
                              ),
                              const SizedBox(height: 2),
                              if (taggedMessage.type == "file" &&
                                  taggedMessage.fileName != null)
                                Row(
                                  children: [
                                    Icon(
                                      Icons.attach_file,
                                      size: 14,
                                      color: Colors.grey[600],
                                    ),
                                    const SizedBox(width: 4),
                                    Expanded(
                                      child: Text(
                                        taggedMessage.fileName!,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                        style: TextStyle(
                                          fontSize: 13,
                                          color: Colors.grey[700],
                                        ),
                                      ),
                                    ),
                                  ],
                                )
                              else
                                Text(
                                  taggedMessage.message,
                                  maxLines: 2,
                                  overflow: TextOverflow.ellipsis,
                                  style: TextStyle(
                                    fontSize: 13,
                                    color: Colors.grey[700],
                                  ),
                                ),
                            ],
                          ),
                        ),
                        IconButton(
                          icon: const Icon(Icons.close, size: 20),
                          padding: EdgeInsets.zero,
                          onPressed: () {
                            ref.read(taggedMessageProvider.notifier).state =
                                null;
                          },
                        ),
                      ],
                    ),
                  ),
                ),
            ],
          ),
          if (showScrollButton)
            Positioned(
              bottom: 150,
              right: 20,
              child: FloatingActionButton(
                heroTag: "scrollBtn",
                backgroundColor: Colors.green,
                mini: true,
                onPressed: () {
                  scrollToBottom(animated: true);
                },
                child: const Icon(Icons.arrow_downward, color: Colors.white),
              ),
            ),
        ],
      ),
    );
  }
}
