import { useEffect, useState, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import { store } from "./store/store.js";
import "./App.css";
import Sidebar from "./components/Sidebar";
import RoomList from "./components/RoomList";
import ChatArea from "./components/ChatArea";
import MemberList from "./components/MemberList";
import CreateSpace from "./components/createspace/CreateSpace";
import CreateAgent from "./components/createspace/CreateAgent";
import CreateSpaceTips from "./components/createspace/CreateSpaceTips";
import CreateAgentTips from "./components/createspace/CreateAgentTips";
import ManageAgent from "./components/createspace/ManageAgent";
import ManageAgentTips from "./components/createspace/ManageAgentTips";
import LoginPage from "./pages/LoginPage";
import AppLoadingScreen from "./components/AppLoadingScreen";
import { initializeAuth } from "./store/slices/authSlice";
import {
  addMessage as addDMMessage,
  updateMessage as updateDMMessage,
  updateConversationLastMessage,
  incrementUnreadCount,
  addConversation,
  clearUnreadCount,
  setOnlineUsers,
  updateUserStatus,
  preloadAllData,
} from "./store/slices/dmSlice";
import { addMessage } from "./store/slices/messageSlice";
import {
  updateRoomLastMessage,
  incrementRoomUnreadCount,
  addJoinedRoom,
} from "./store/slices/spaceSlice";
import socketService from "./services/socket.service";

function App() {
  const dispatch = useDispatch();
  const { activeView, activeSpace, activeRoom, searchQuery, isSettings } =
    useSelector((state) => state.app);
  const { isAuthenticated, initialized, loading, isLoggingOut } = useSelector(
    (state) => state.auth,
  );
  const { appLoading, appLoadingPhase } = useSelector((state) => state.app);

  const [createTab, setCreateTab] = useState("space");
  const [editingAgent, setEditingAgent] = useState(null);
  const [roomListCollapsed, setRoomListCollapsed] = useState(false);
  const [memberListCollapsed, setMemberListCollapsed] = useState(false);
  const [isCreatingRoom, setIsCreatingRoom] = useState(false);
  const [isRoomSettingsOpen, setIsRoomSettingsOpen] = useState(false);

  // 1. Auth initialization
  useEffect(() => {
    if (window.location.pathname !== "/") {
      window.history.replaceState(null, "", "/");
    }
    if (!initialized && !loading) {
      dispatch(initializeAuth());
    }
  }, [dispatch, initialized, loading]);

  // 2. Fetch ALL data once after auth is ready
  const preloadStartTime = useRef(null);
  useEffect(() => {
    if (!isAuthenticated || !initialized) return;
    preloadStartTime.current = performance.now();
    dispatch(preloadAllData());
  }, [isAuthenticated, initialized, dispatch]);

  // Log preload time when loading finishes
  useEffect(() => {
    if (!appLoading && preloadStartTime.current !== null) {
      const elapsed = Math.round(performance.now() - preloadStartTime.current);
      console.log(`%c[Preload] Tất cả data đã load xong trong ${elapsed}ms`, "color: #22c55e; font-weight: bold; font-size: 14px;");
      preloadStartTime.current = null;
    }
  }, [appLoading]);

  // 3. Connect WebSocket when authenticated
  useEffect(() => {
    if (isAuthenticated) {
      socketService.connect();
    } else {
      socketService.disconnect();
    }

    return () => {
      socketService.disconnect();
    };
  }, [isAuthenticated]);

  // ============================================
  // Global WebSocket DM Listener — REGISTERED ONCE ONLY
  // ============================================
  useEffect(() => {
    if (!isAuthenticated) return;

    const handleNewDM = (data) => {
      if (!data?.id) return;

      const conversationId = data.conversation_id || data.conversationId;
      if (!conversationId) return;

      const now = Date.now();
      const isOwn = String(data.sender_id) === String(store.getState().auth.user?.id);
      if (!isOwn && data.clientSentAt) {
        const receiveDelay = now - data.clientSentAt;
        console.log(
          `%c[DM Latency] RECEIVE | delay: ${receiveDelay}ms | from: ${data.sender?.display_name || data.sender_id} | msgId: ${data.id}`,
          "color: #3b82f6; font-weight: bold;",
        );
      }

      const state = store.getState();
      const currentConversations = state.dm.conversations;
      const currentActiveId = state.dm.activeConversationId;
      const currentUserId = state.auth.user?.id;

      const convExists = currentConversations.some((c) => c.id === conversationId);
      if (!convExists && data.conversation) {
        dispatch(addConversation(data.conversation));
      } else if (!convExists && data.sender) {
        dispatch(
          addConversation({
            id: conversationId,
            other_user: data.sender,
            last_message: {
              id: data.id,
              content: data.content,
              created_at: data.created_at || data.timestamp,
            },
            unread_count: 0,
            created_at: data.created_at || data.timestamp,
          }),
        );
      }

      if (!convExists) {
        socketService.joinDM(conversationId);
      }

      dispatch(
        addDMMessage({
          conversationId,
          message: {
            id: data.id,
            conversation_id: conversationId,
            sender_id: data.sender_id,
            content: data.content,
            is_read: data.is_read ?? false,
            created_at: data.created_at || data.timestamp,
            sender: data.sender,
            tempId: data.tempId || data.temp_id,
          },
        }),
      );

      dispatch(
        updateConversationLastMessage({
          conversationId,
          message: {
            id: data.id,
            content: data.content,
            created_at: data.created_at || data.timestamp,
          },
        }),
      );

      const isOwnMessage = String(data.sender_id) === String(currentUserId);
      if (conversationId !== currentActiveId && !isOwnMessage) {
        dispatch(incrementUnreadCount({ conversationId }));
      }
    };

    const handleDmSent = (data) => {
      if (!data?.success || !data?.message) return;
      const msg = data.message;
      const conversationId = msg.conversation_id || msg.conversationId;
      const tempId = data.tempId || data.temp_id;
      if (!conversationId) return;

      dispatch(
        addDMMessage({
          conversationId,
          message: {
            id: msg.id,
            conversation_id: conversationId,
            sender_id: msg.sender_id,
            content: msg.content,
            is_read: msg.is_read ?? false,
            created_at: msg.created_at || msg.timestamp,
            sender: msg.sender,
            tempId,
          },
        }),
      );

      dispatch(
        updateConversationLastMessage({
          conversationId,
          message: {
            id: msg.id,
            content: msg.content,
            created_at: msg.created_at || msg.timestamp,
          },
        }),
      );
    };

    const handleDmMarkedRead = (data) => {
      if (!data?.conversationId || !data?.messageId) return;
      dispatch(
        updateDMMessage({
          conversationId: data.conversationId,
          messageId: data.messageId,
          updates: { is_read: true },
        }),
      );
    };

    const handleConnected = (data) => {
      if (data?.onlineUsers) {
        dispatch(setOnlineUsers(data.onlineUsers));
      }
    };

    const handleUserStatusChanged = (data) => {
      if (!data?.userId) return;
      dispatch(updateUserStatus({ userId: data.userId, status: data.status }));
    };

    const handleNewMessage = (data) => {
      console.log("[App] newMessage received:", JSON.stringify(data, null, 2));
      const roomId = data.room_id || data.roomId;
      const content = data.content;
      const author = data.author;
      const senderId = data.user_id || data.senderId;
      const id = data.id;
      const tempId = data.tempId;

      if (!roomId || !content) return;

      console.log("[App] newMessage parsed:", { roomId, id, tempId, author, senderId });

      const state = store.getState();
      const currentActiveRoom = state.app.activeRoom;
      const currentUserId = state.auth.user?.id;
      const isOwnMessage = String(senderId) === String(currentUserId);

      // 1. Save message to Redux
      dispatch(
        addMessage({
          roomId,
          message: {
            id: id || Date.now(),
            sender: {
              id: senderId,
              display_name: author?.display_name || author?.username || "Unknown",
              avatar_url: author?.avatar_url || null,
            },
            sender_id: senderId,
            content,
            created_at: data.created_at || new Date().toISOString(),
            isPinned: data.is_pinned || false,
            isOwn: isOwnMessage,
            tempId,
          },
        }),
      );

      // 2. Update room's last_message in spaceSlice (for RoomList display)
      dispatch(
        updateRoomLastMessage({
          roomId,
          message: {
            id: id || Date.now(),
            content,
            created_at: data.created_at || new Date().toISOString(),
            sender_id: senderId,
            sender: author,
          },
        }),
      );

      // 3. Increment unread count if not viewing this room and not own message
      if (roomId !== currentActiveRoom && !isOwnMessage) {
        dispatch(incrementRoomUnreadCount({ roomId }));
      }
    };

    socketService.onConnected(handleConnected);
    socketService.onUserStatusChanged(handleUserStatusChanged);
    socketService.onNewDM(handleNewDM);
    socketService.onDmSent(handleDmSent);
    socketService.onDmMarkedRead(handleDmMarkedRead);
    socketService.onNewMessage(handleNewMessage);

    return () => {
      socketService.off("connected", handleConnected);
      socketService.off("userStatusChanged", handleUserStatusChanged);
      socketService.off("newDM", handleNewDM);
      socketService.off("dmSent", handleDmSent);
      socketService.off("dmMarkedRead", handleDmMarkedRead);
      socketService.off("newMessage", handleNewMessage);
    };
  }, [isAuthenticated, dispatch]);

  const currentView = isSettings ? "settings" : activeView;

  // Not initialized yet (checking auth state) OR logging out
  if (!initialized || isLoggingOut) {
    return <AppLoadingScreen />;
  }

  if (!isAuthenticated) {
    return <LoginPage />;
  }

  // 🆕 Loading all data after login
  if (appLoading) {
    return <AppLoadingScreen />;
  }

  const handleEditAgent = (agent) => {
    setEditingAgent(agent);
    setCreateTab("editAgent");
  };

  const handleCancelEdit = () => {
    setEditingAgent(null);
    setCreateTab("manageAgent");
  };

  const renderCreateContent = () => {
    switch (createTab) {
      case "agent":
        return <CreateAgent />;
      case "manageAgent":
        return <ManageAgent onEditAgent={handleEditAgent} />;
      case "editAgent":
        return (
          <CreateAgent
            editMode
            initialData={editingAgent}
            onCancel={handleCancelEdit}
          />
        );
      default:
        return <CreateSpace />;
    }
  };

  const renderCreateTips = () => {
    switch (createTab) {
      case "agent":
        return <CreateAgentTips />;
      case "manageAgent":
        return <ManageAgentTips />;
      case "editAgent":
        return <CreateAgentTips />;
      default:
        return <CreateSpaceTips />;
    }
  };

  return (
    <div className="w-screen h-screen flex overflow-hidden">
      <Sidebar />
      {currentView === "createSpace" ? (
        <>
          <RoomList
            activeView="createSpace"
            createTab={createTab}
            onCreateTabChange={setCreateTab}
          />
          {renderCreateContent()}
          {renderCreateTips()}
        </>
      ) : (
        <>
          <div
            className="flex-shrink-0 h-screen overflow-hidden transition-all duration-300 ease-in-out"
            style={{
              width: roomListCollapsed ? 0 : 240,
              minWidth: roomListCollapsed ? 0 : 240,
              opacity: roomListCollapsed ? 0 : 1,
            }}
          >
            <RoomList
              activeView={currentView}
              activeSpace={activeSpace}
              activeRoom={activeRoom}
              searchQuery={searchQuery}
              onCreateRoomClick={() => setIsCreatingRoom(true)}
            />
          </div>

          {/* Collapsed room list indicator */}
          {roomListCollapsed && (
            <div
              className="flex-shrink-0 h-screen flex flex-col items-center justify-center cursor-pointer border-r transition-colors duration-200"
              style={{
                width: 8,
                minWidth: 8,
                background: "var(--bg-surface-secondary)",
                borderColor: "var(--border-primary)",
              }}
              onClick={() => setRoomListCollapsed(false)}
              onMouseEnter={(e) => {
                e.currentTarget.style.background = "var(--hover-primary)";
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.background = "var(--bg-surface-secondary)";
              }}
              title="Hiện danh sách room"
            >
              <div
                className="w-[2px] h-8 rounded-full"
                style={{ background: "var(--border-primary)" }}
              />
            </div>
          )}

          <ChatArea
            activeView={currentView}
            activeRoom={activeRoom}
            onToggleRoomList={() => setRoomListCollapsed((p) => !p)}
            onToggleMemberList={() => setMemberListCollapsed((p) => !p)}
            roomListCollapsed={roomListCollapsed}
            memberListCollapsed={memberListCollapsed}
            isCreatingRoom={isCreatingRoom}
            onCancelCreateRoom={() => setIsCreatingRoom(false)}
            isRoomSettingsOpen={isRoomSettingsOpen}
            onOpenRoomSettings={() => setIsRoomSettingsOpen(true)}
            onCloseRoomSettings={() => setIsRoomSettingsOpen(false)}
          />

          {/* Collapsed member list indicator */}
          {memberListCollapsed && (
            <div
              className="flex-shrink-0 h-screen flex flex-col items-center justify-center cursor-pointer border-l transition-colors duration-200"
              style={{
                width: 8,
                minWidth: 8,
                background: "var(--bg-surface-secondary)",
                borderColor: "var(--border-primary)",
              }}
              onClick={() => setMemberListCollapsed(false)}
              onMouseEnter={(e) => {
                e.currentTarget.style.background = "var(--hover-primary)";
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.background = "var(--bg-surface-secondary)";
              }}
              title="Hiện danh sách thành viên"
            >
              <div
                className="w-[2px] h-8 rounded-full"
                style={{ background: "var(--border-primary)" }}
              />
            </div>
          )}

          <div
            className="flex-shrink-0 h-screen overflow-hidden transition-all duration-300 ease-in-out"
            style={{
              width: memberListCollapsed ? 0 : 240,
              minWidth: memberListCollapsed ? 0 : 240,
              opacity: memberListCollapsed ? 0 : 1,
            }}
          >
            <MemberList activeView={currentView} activeRoom={activeRoom} />
          </div>
        </>
      )}
    </div>
  );
}

export default App;
