import { useCallback, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useRoom, useUser } from '@/contexts';
import { RoomProvider } from '@/contexts';
import { Loader2 } from 'lucide-react';
import { CreateRoomDialog } from '@/components/room/CreateRoomDialog';
import { DeleteRoomAlert } from '@/components/room/DeleteRoomAlert';
import { EditRoomDialog } from '@/components/room/EditRoomDialog';
import { DiscordChannelSidebar } from '@/components/room/DiscordChannelSidebar';
import { DiscordChatPanel } from '@/components/room/DiscordChatPanel';

function ProjectRoomInner() {
  const params = useParams();
  const projectName = params['project_name'] ?? '';

  const { user } = useUser();

  const {
    rooms,
    roomsLoading,
    categories,
    createCategory,
    activeRoom,
    activeRoomId,
    setActiveRoom,
    createRoom,
    updateRoom,
    deleteRoom,
    members,
  } = useRoom();

  const [showChannelSidebar, setShowChannelSidebar] = useState(true);
  const [createDialogOpen, setCreateDialogOpen] = useState(false);
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [roomName, setRoomName] = useState('');
  const [roomPublic, setRoomPublic] = useState(true);
  const [isPending, setIsPending] = useState(false);

  const handleSelectRoom = (room: { id: string }) => {
    setActiveRoom(room.id);
  };

  const handleClose = () => {
    setActiveRoom(null);
  };

  const handleOpenCreate = () => {
    setRoomName('');
    setRoomPublic(true);
    setCreateDialogOpen(true);
  };

  const handleCreateSubmit = async () => {
    if (!roomName.trim()) return;
    setIsPending(true);
    try {
      const newRoom = await createRoom(roomName.trim(), roomPublic);
      setCreateDialogOpen(false);
      setActiveRoom(newRoom.id);
    } catch (err) {
      console.error('Failed to create room:', err);
    } finally {
      setIsPending(false);
    }
  };

  const handleEditSubmit = async () => {
    if (!activeRoom || !roomName.trim()) return;
    setIsPending(true);
    try {
      await updateRoom(activeRoom.id, roomName.trim(), roomPublic);
      setEditDialogOpen(false);
    } catch (err) {
      console.error('Failed to update room:', err);
    } finally {
      setIsPending(false);
    }
  };

  const handleDeleteConfirm = async () => {
    if (!activeRoom) return;
    setIsPending(true);
    try {
      await deleteRoom(activeRoom.id);
      setDeleteDialogOpen(false);
      setActiveRoom(null);
    } catch (err) {
      console.error('Failed to delete room:', err);
    } finally {
      setIsPending(false);
    }
  };

  const handleCreateCategory = useCallback(async (name: string) => {
    await createCategory(name);
  }, [createCategory]);

  const handleMoveRoomToCategory = useCallback(
    async (roomId: string, categoryId: string | null) => {
      await updateRoom(roomId, undefined, undefined, categoryId ?? undefined);
    },
    [updateRoom],
  );

  const isAdmin = !!user && members.some(
    (m) =>
      m.user === user.uid &&
      (m.role === 'owner' || m.role === 'admin'),
  );

  if (roomsLoading) {
    return (
      <div className="flex flex-1 items-center justify-center">
        <Loader2 className="h-7 w-7 animate-spin text-muted-foreground" />
      </div>
    );
  }

  return (
    <div className="discord-layout">
      {/* Channel sidebar */}
      {showChannelSidebar && (
        <DiscordChannelSidebar
          projectName={projectName}
          rooms={rooms}
          selectedRoomId={activeRoomId}
          onSelectRoom={handleSelectRoom}
          onCreateRoom={handleOpenCreate}
          categories={categories.map((c) => ({ id: c.id, name: c.name }))}
          onCreateCategory={handleCreateCategory}
          onMoveRoomToCategory={handleMoveRoomToCategory}
        />
      )}

      {/* Main chat area */}
      {activeRoom ? (
        <DiscordChatPanel
          room={activeRoom}
          isAdmin={isAdmin}
          onClose={handleClose}
          onToggleChannelSidebar={() => setShowChannelSidebar((v) => !v)}
          channelSidebarOpen={showChannelSidebar}
          onDelete={() => setDeleteDialogOpen(true)}
        />
      ) : (
        <div className="flex flex-1 items-center justify-center bg-background">
          <div className="text-center px-6 py-8">
            <div className="text-5xl mb-4 text-foreground/20">#</div>
            <p className="text-lg font-medium text-foreground/60">Select a channel</p>
            <p className="text-sm mt-1 text-muted-foreground/60">
              Choose a channel from the sidebar to start chatting.
            </p>
          </div>
        </div>
      )}

      <CreateRoomDialog
        open={createDialogOpen}
        onOpenChange={setCreateDialogOpen}
        roomName={roomName}
        roomPublic={roomPublic}
        onRoomNameChange={setRoomName}
        onRoomPublicChange={setRoomPublic}
        onSubmit={handleCreateSubmit}
        isPending={isPending}
      />

      <EditRoomDialog
        open={editDialogOpen}
        onOpenChange={setEditDialogOpen}
        roomName={roomName}
        roomPublic={roomPublic}
        onRoomNameChange={setRoomName}
        onRoomPublicChange={setRoomPublic}
        onSubmit={handleEditSubmit}
        isPending={isPending}
      />

      <DeleteRoomAlert
        open={deleteDialogOpen}
        onOpenChange={setDeleteDialogOpen}
        roomName={activeRoom?.room_name ?? ''}
        onConfirm={handleDeleteConfirm}
        isPending={isPending}
      />
    </div>
  );
}

export function ProjectRoom() {
  const params = useParams();
  const projectName = params['project_name'] ?? null;
  const roomIdFromUrl = params['roomId'] ?? null;

  return (
    <RoomProvider projectName={projectName} initialRoomId={roomIdFromUrl}>
      <ProjectRoomInner />
    </RoomProvider>
  );
}
