import React, { useState, useEffect } from "react";
import { Conversation, Message, User } from "../types";
import { messageAPI } from "../services/api";
import { useAuth } from "../contexts/AuthContext";
import { useSocket } from "../contexts/SocketContext";
import ChatWindow from "../components/ChatWindow";
import Avatar from "../components/Avatar";

const Messages: React.FC = () => {
  const { user } = useAuth();
  const { isConnected, onNewMessage, onMessageRead } = useSocket();
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedRecipient, setSelectedRecipient] = useState<User | null>(null);
  const [showChat, setShowChat] = useState(false);

  useEffect(() => {
    fetchConversations();
  }, []);

  // Listen for new messages and update conversations in real-time
  useEffect(() => {
    if (!isConnected) return;

    const cleanup = onNewMessage((newMessage: Message) => {
      setConversations((prevConversations) => {
        // Determine conversation partner
        const partnerId =
          newMessage.senderId === user?.id
            ? newMessage.receiverId
            : newMessage.senderId;

        // Find existing conversation
        const existingIndex = prevConversations.findIndex(
          (c) => c.partnerId === partnerId
        );

        if (existingIndex !== -1) {
          // Update existing conversation
          const updated = [...prevConversations];
          const conv = { ...updated[existingIndex] };

          conv.lastMessage = {
            id: newMessage.id,
            content: newMessage.content,
            senderId: newMessage.senderId,
            createdAt: newMessage.createdAt,
            isRead: newMessage.isRead,
          };
          conv.lastMessageAt = newMessage.createdAt;

          // Increment unread count if user received the message
          if (newMessage.receiverId === user?.id && !newMessage.isRead) {
            conv.unreadCount++;
          }

          updated[existingIndex] = conv;

          // Re-sort by most recent
          updated.sort(
            (a, b) =>
              new Date(b.lastMessageAt).getTime() -
              new Date(a.lastMessageAt).getTime()
          );

          return updated;
        } else {
          // New conversation - add to top
          const partner =
            newMessage.senderId === user?.id
              ? newMessage.receiver!
              : newMessage.sender!;

          if (!partner) {
            return prevConversations;
          }

          const newConv: Conversation = {
            partnerId,
            partner,
            lastMessage: {
              id: newMessage.id,
              content: newMessage.content,
              senderId: newMessage.senderId,
              createdAt: newMessage.createdAt,
              isRead: newMessage.isRead,
            },
            unreadCount:
              newMessage.receiverId === user?.id && !newMessage.isRead ? 1 : 0,
            lastMessageAt: newMessage.createdAt,
          };

          return [newConv, ...prevConversations];
        }
      });
    });

    return cleanup;
  }, [isConnected, user?.id, onNewMessage]);

  // Listen for read receipts and update unread counts
  useEffect(() => {
    if (!isConnected) return;

    const cleanup = onMessageRead((data: any) => {
      setConversations((prevConversations) => {
        return prevConversations.map((conv) => {
          // If this is the conversation and the last message was marked as read
          if (
            conv.lastMessage.id === data.messageId &&
            !conv.lastMessage.isRead
          ) {
            return {
              ...conv,
              lastMessage: { ...conv.lastMessage, isRead: true },
              unreadCount: Math.max(0, conv.unreadCount - 1),
            };
          }
          return conv;
        });
      });
    });

    return cleanup;
  }, [isConnected, onMessageRead]);

  const fetchConversations = async () => {
    try {
      const response = await messageAPI.getConversations();
      setConversations(response.data);
    } catch (err: any) {
      setError(err.response?.data?.error || "Failed to fetch conversations");
    } finally {
      setLoading(false);
    }
  };

  const formatDate = (dateString: string) => {
    const date = new Date(dateString);
    const now = new Date();
    const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60);

    if (diffInHours < 24) {
      return date.toLocaleTimeString("en-US", {
        hour: "numeric",
        minute: "2-digit",
      });
    } else if (diffInHours < 48) {
      return "Yesterday";
    } else {
      return date.toLocaleDateString("en-US", {
        month: "short",
        day: "numeric",
      });
    }
  };

  const handleConversationClick = (conversation: Conversation) => {
    setSelectedRecipient(conversation.partner);
    setShowChat(true);
  };

  const handleMessagesRead = (partnerId: string, count: number) => {
    // Update the conversation's unread count
    setConversations((prevConversations) =>
      prevConversations.map((conv) =>
        conv.partnerId === partnerId ? { ...conv, unreadCount: 0 } : conv
      )
    );
  };

  const handleChatClose = () => {
    setShowChat(false);
    setSelectedRecipient(null);
    // Refresh conversations to get updated unread counts
    fetchConversations();
  };

  if (loading) {
    return (
      <div className="container mt-5">
        <div className="text-center">
          <div className="spinner-border" role="status">
            <span className="visually-hidden">Loading...</span>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="container mt-4">
      <div className="row justify-content-center">
        <div className="col-md-8">
          <h1 className="mb-4">Messages</h1>

          {error && (
            <div className="alert alert-danger" role="alert">
              {error}
            </div>
          )}

          {conversations.length === 0 ? (
            <div className="text-center py-5">
              <i
                className="bi bi-envelope"
                style={{ fontSize: "3rem", color: "#ccc" }}
              ></i>
              <p className="text-muted mt-2">No conversations yet</p>
            </div>
          ) : (
            <div className="list-group">
              {conversations.map((conversation) => {
                const isUnread = conversation.unreadCount > 0;
                const isLastMessageFromPartner =
                  conversation.lastMessage.senderId === conversation.partnerId;

                return (
                  <div
                    key={conversation.partnerId}
                    className={`list-group-item list-group-item-action ${
                      isUnread ? "border-start border-primary border-4" : ""
                    }`}
                    onClick={() => handleConversationClick(conversation)}
                    style={{
                      cursor: "pointer",
                      backgroundColor: isUnread ? "#f0f7ff" : "white",
                    }}
                  >
                    <div className="d-flex w-100 justify-content-between align-items-start">
                      <div className="d-flex align-items-center flex-grow-1">
                        {/* Profile Picture */}
                        <Avatar user={conversation.partner} size="lg" className="me-3" />

                        <div className="flex-grow-1" style={{ minWidth: 0 }}>
                          {/* User Name and Unread Badge */}
                          <div className="d-flex align-items-center mb-1">
                            <h6 className={`mb-0 ${isUnread ? "fw-bold" : ""}`}>
                              {conversation.partner.firstName}{" "}
                              {conversation.partner.lastName}
                            </h6>
                            {isUnread && (
                              <span className="badge bg-primary ms-2">
                                {conversation.unreadCount}
                              </span>
                            )}
                          </div>

                          {/* Last Message Preview */}
                          <p
                            className={`mb-0 text-truncate ${
                              isUnread && isLastMessageFromPartner
                                ? "fw-semibold"
                                : "text-muted"
                            }`}
                            style={{ maxWidth: "100%" }}
                          >
                            {conversation.lastMessage.senderId === user?.id && (
                              <span className="me-1">You: </span>
                            )}
                            {conversation.lastMessage.content}
                          </p>
                        </div>
                      </div>

                      {/* Timestamp */}
                      <div
                        className="text-end ms-3"
                        style={{ minWidth: "fit-content" }}
                      >
                        <small className="text-muted d-block">
                          {formatDate(conversation.lastMessageAt)}
                        </small>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>

      {selectedRecipient && (
        <ChatWindow
          show={showChat}
          onClose={handleChatClose}
          recipient={selectedRecipient}
          onMessagesRead={handleMessagesRead}
        />
      )}
    </div>
  );
};

export default Messages;
