import React, { useState, useEffect, useCallback } from 'react';
import { useAuth } from '../context/AuthContext';
import { useSocket } from '../context/SocketContext';
import ServerList from './ServerList';
import ChannelSidebar from './ChannelSidebar';

// Lazy-loaded modals — these will be built in a separate batch
const CreateServerModal = React.lazy(() => import('./modals/CreateServerModal'));
const ServerSettings = React.lazy(() => import('./modals/ServerSettings'));
const UserSettings = React.lazy(() => import('./modals/UserSettings'));
const InviteModal = React.lazy(() => import('./modals/InviteModal'));

// Chat area — will be built separately
const ChatArea = React.lazy(() => import('./ChatArea'));
const MemberList = React.lazy(() => import('./MemberList'));

export default function Layout() {
  const { user, token } = useAuth();
  const { socket } = useSocket();

  const [servers, setServers] = useState([]);
  const [activeServer, setActiveServer] = useState(null);
  const [activeChannel, setActiveChannel] = useState(null);
  const [serverDetail, setServerDetail] = useState(null);

  const [showServerSettings, setShowServerSettings] = useState(false);
  const [showUserSettings, setShowUserSettings] = useState(false);
  const [showCreateServer, setShowCreateServer] = useState(false);
  const [showInviteModal, setShowInviteModal] = useState(false);
  const [showMemberList, setShowMemberList] = useState(true);

  // Fetch user's servers
  const fetchServers = useCallback(async () => {
    try {
      const res = await fetch('/api/servers', {
        headers: { Authorization: `Bearer ${token}` },
      });
      if (!res.ok) return;
      const data = await res.json();
      const list = data.servers || data;
      setServers(list);

      // Auto-select first server if none active
      if (!activeServer && list.length > 0) {
        setActiveServer(list[0]);
      }
    } catch (err) {
      console.error('Failed to fetch servers:', err);
    }
  }, [token, activeServer]);

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

  // Fetch full server detail when active server changes
  useEffect(() => {
    if (!activeServer) {
      setServerDetail(null);
      setActiveChannel(null);
      return;
    }

    const fetchDetail = async () => {
      try {
        const res = await fetch(`/api/servers/${activeServer.id}`, {
          headers: { Authorization: `Bearer ${token}` },
        });
        if (!res.ok) return;
        const data = await res.json();
        const detail = data.server || data;
        setServerDetail(detail);

        // Auto-select first channel
        if (detail.channels && detail.channels.length > 0) {
          setActiveChannel(detail.channels[0]);
        } else if (detail.categories) {
          for (const cat of detail.categories) {
            if (cat.channels && cat.channels.length > 0) {
              setActiveChannel(cat.channels[0]);
              break;
            }
          }
        }
      } catch (err) {
        console.error('Failed to fetch server detail:', err);
      }
    };

    fetchDetail();

    // Join server room via socket
    if (socket) {
      socket.emit('server:join', activeServer.id);
    }

    return () => {
      if (socket && activeServer) {
        socket.emit('server:leave', activeServer.id);
      }
    };
  }, [activeServer?.id, token, socket]);

  // Socket listeners for server updates
  useEffect(() => {
    if (!socket) return;

    const handleServerUpdate = (data) => {
      setServers((prev) =>
        prev.map((s) => (s.id === data.id ? { ...s, ...data } : s))
      );
      if (activeServer?.id === data.id) {
        setActiveServer((prev) => (prev ? { ...prev, ...data } : prev));
      }
    };

    socket.on('server:updated', handleServerUpdate);

    return () => {
      socket.off('server:updated', handleServerUpdate);
    };
  }, [socket, activeServer?.id]);

  const handleSelectServer = (server) => {
    setActiveServer(server);
  };

  const handleOpenDMs = () => {
    setActiveServer(null);
    setServerDetail(null);
    setActiveChannel(null);
  };

  const handleSelectChannel = (channel) => {
    setActiveChannel(channel);
  };

  const handleServerCreated = (newServer) => {
    setServers((prev) => [...prev, newServer]);
    setActiveServer(newServer);
    setShowCreateServer(false);
  };

  const dmMode = activeServer === null;

  return (
    <div className="flex h-screen bg-[#0e0e10] overflow-hidden">
      {/* Server List */}
      <ServerList
        servers={servers}
        activeServer={activeServer}
        onSelectServer={handleSelectServer}
        onOpenDMs={handleOpenDMs}
        onCreateServer={() => setShowCreateServer(true)}
        onOpenUserSettings={() => setShowUserSettings(true)}
        user={user}
      />

      {/* Channel Sidebar */}
      <ChannelSidebar
        server={serverDetail}
        activeChannel={activeChannel}
        onSelectChannel={handleSelectChannel}
        onOpenServerSettings={() => setShowServerSettings(true)}
        onOpenInvite={() => setShowInviteModal(true)}
        dmMode={dmMode}
        user={user}
        token={token}
      />

      {/* Chat Area */}
      <div className="flex-1 flex flex-col min-w-0">
        <React.Suspense
          fallback={
            <div className="flex-1 flex items-center justify-center bg-[#1e1e22]">
              <div className="w-8 h-8 border-3 border-[#FFD700] border-t-transparent rounded-full animate-spin" />
            </div>
          }
        >
          <ChatArea
            server={activeServer}
            channel={activeChannel}
            token={token}
            user={user}
            socket={socket}
            onToggleMemberList={() => setShowMemberList((v) => !v)}
            showMemberList={showMemberList}
          />
        </React.Suspense>
      </div>

      {/* Member List */}
      {showMemberList && activeServer && (
        <React.Suspense fallback={null}>
          <MemberList server={activeServer} token={token} />
        </React.Suspense>
      )}

      {/* Modals */}
      <React.Suspense fallback={null}>
        {showCreateServer && (
          <CreateServerModal
            onClose={() => setShowCreateServer(false)}
            onCreated={handleServerCreated}
            token={token}
          />
        )}
        {showServerSettings && serverDetail && (
          <ServerSettings
            server={serverDetail}
            onClose={() => setShowServerSettings(false)}
            token={token}
            onUpdate={(updated) => {
              setServerDetail((prev) => ({ ...prev, ...updated }));
              setServers((prev) =>
                prev.map((s) => (s.id === updated.id ? { ...s, ...updated } : s))
              );
            }}
          />
        )}
        {showUserSettings && (
          <UserSettings onClose={() => setShowUserSettings(false)} />
        )}
        {showInviteModal && activeServer && (
          <InviteModal
            server={activeServer}
            onClose={() => setShowInviteModal(false)}
            token={token}
          />
        )}
      </React.Suspense>
    </div>
  );
}
