"use client";

import styles from "./sidePanel.module.css";

import { useEffect, useMemo, useState } from "react";

import { mutate } from "swr";

import { UserProfile, useAuthenticatedData } from "@/app/common/auth";
import Link from "next/link";
import useSWR from "swr";

import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from "@/components/ui/command";

import { InlineLoading } from "../loading/loading";

import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from "@/components/ui/dialog";

import {
    Drawer,
    DrawerClose,
    DrawerContent,
    DrawerDescription,
    DrawerFooter,
    DrawerHeader,
    DrawerTitle,
    DrawerTrigger,
} from "@/components/ui/drawer";

import { ScrollArea } from "@/components/ui/scroll-area";

import {
    ArrowRight,
    ArrowLeft,
    ArrowDown,
    Spinner,
    Check,
    FolderPlus,
    DotsThreeVertical,
    House,
    StackPlus,
    UserCirclePlus,
    Sidebar,
    NotePencil,
    FunnelSimple,
    MagnifyingGlass,
    ChatsCircle,
} from "@phosphor-icons/react";

interface ChatHistory {
    conversation_id: string;
    slug: string;
    agent_name: string;
    agent_icon: string;
    agent_color: string;
    compressed: boolean;
    created: string;
    updated: string;
}

import {
    DropdownMenu,
    DropdownMenuCheckboxItem,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuLabel,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";

import { Pencil, Trash, Share } from "@phosphor-icons/react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { modifyFileFilterForConversation } from "@/app/common/chatFunctions";
import { ScrollAreaScrollbar } from "@radix-ui/react-scroll-area";
import { getIconFromIconName } from "@/app/common/iconUtils";
import {
    SidebarGroup,
    SidebarGroupLabel,
    SidebarMenuAction,
    SidebarMenuButton,
    SidebarMenuItem,
    SidebarMenuSkeleton,
} from "@/components/ui/sidebar";

// Define a fetcher function
const fetcher = (url: string) =>
    fetch(url).then((res) => {
        if (!res.ok) throw new Error(`Failed to call API at ${url} with error ${res.statusText}`);
        return res.json();
    });

interface GroupedChatHistory {
    [key: string]: ChatHistory[];
}

function renameConversation(conversationId: string, newTitle: string) {
    const editUrl = `/api/chat/title?client=web&conversation_id=${conversationId}&title=${newTitle}`;

    fetch(editUrl, {
        method: "PATCH",
        headers: {
            "Content-Type": "application/json",
        },
    })
        .then((response) => response.json())
        .then((data) => {})
        .catch((err) => {
            console.error(err);
            return;
        });
}

function shareConversation(conversationId: string, setShareUrl: (url: string) => void) {
    const shareUrl = `/api/chat/share?client=web&conversation_id=${conversationId}`;

    fetch(shareUrl, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
    })
        .then((response) => response.json())
        .then((data) => {
            setShareUrl(data.url);
        })
        .catch((err) => {
            console.error(err);
            return;
        });
}

function deleteConversation(conversationId: string) {
    const deleteUrl = `/api/chat/history?client=web&conversation_id=${conversationId}`;

    fetch(deleteUrl, {
        method: "DELETE",
        headers: {
            "Content-Type": "application/json",
        },
    })
        .then((response) => {
            response.json();
            mutate("/api/chat/sessions");
        })
        .then((data) => {})
        .catch((err) => {
            console.error(err);
            return;
        });
}

interface FilesMenuProps {
    conversationId: string | null;
    uploadedFiles: string[];
    isMobileWidth: boolean;
}

function FilesMenu(props: FilesMenuProps) {
    // Use SWR to fetch files
    const { data: files, error } = useSWR<string[]>("/api/content/computer", fetcher);
    const { data: selectedFiles, error: selectedFilesError } = useSWR(
        props.conversationId ? `/api/chat/conversation/file-filters/${props.conversationId}` : null,
        fetcher,
    );
    const [isOpen, setIsOpen] = useState(false);
    const [unfilteredFiles, setUnfilteredFiles] = useState<string[]>([]);
    const [addedFiles, setAddedFiles] = useState<string[]>([]);
    const usingConversationContext = props.conversationId !== null;

    useEffect(() => {
        if (!files) return;

        let sortedUniqueFiles = Array.from(new Set(files)).sort();

        if (Array.isArray(addedFiles)) {
            sortedUniqueFiles = addedFiles.concat(
                sortedUniqueFiles.filter((filename: string) => !addedFiles.includes(filename)),
            );
        }

        setUnfilteredFiles(sortedUniqueFiles);
    }, [files, addedFiles]);

    useEffect(() => {
        for (const file of props.uploadedFiles) {
            setAddedFiles((addedFiles) => [...addedFiles, file]);
        }
    }, [props.uploadedFiles]);

    useEffect(() => {
        if (Array.isArray(selectedFiles)) {
            setAddedFiles(selectedFiles);
        } else {
            setAddedFiles([]);
        }
    }, [selectedFiles]);

    const removeAllFiles = () => {
        modifyFileFilterForConversation(props.conversationId, addedFiles, setAddedFiles, "remove");
    };

    const addAllFiles = () => {
        modifyFileFilterForConversation(
            props.conversationId,
            unfilteredFiles,
            setAddedFiles,
            "add",
        );
    };

    if (error) return <div>Failed to load files</div>;
    if (selectedFilesError) return <div>Failed to load selected files</div>;
    if (!files) return <InlineLoading />;
    if (!selectedFiles && props.conversationId) return <InlineLoading />;

    const FilesMenuCommandBox = () => {
        return (
            <Command>
                <CommandInput placeholder="Find file" />
                <CommandList>
                    <CommandEmpty>
                        No results found. <Link href="/search">Try advanced search</Link>.
                    </CommandEmpty>
                    {usingConversationContext && (
                        <CommandGroup heading="Quick">
                            <CommandItem
                                onSelect={() => {
                                    removeAllFiles();
                                }}
                            >
                                <Trash className="h-4 w-4 mr-2" />
                                <span>Clear all</span>
                            </CommandItem>
                            <CommandItem
                                onSelect={() => {
                                    addAllFiles();
                                }}
                            >
                                <FolderPlus className="h-4 w-4 mr-2" />
                                <span>Select all</span>
                            </CommandItem>
                        </CommandGroup>
                    )}
                    <CommandGroup heading="Manage files">
                        <CommandItem>
                            <Link href="/settings">Settings</Link>
                        </CommandItem>
                    </CommandGroup>
                    <CommandGroup
                        heading={`${usingConversationContext ? "Configure files" : "Synced files"}`}
                    >
                        {addedFiles.length == 0 && (
                            <CommandItem>
                                <Link href="/settings">Upload documents</Link>
                            </CommandItem>
                        )}
                        {unfilteredFiles.map((filename: string) =>
                            Array.isArray(addedFiles) && addedFiles.includes(filename) ? (
                                <CommandItem
                                    key={filename}
                                    value={filename}
                                    className="bg-accent text-accent-foreground mb-1"
                                    onSelect={(value) => {
                                        if (!usingConversationContext) return;

                                        modifyFileFilterForConversation(
                                            props.conversationId,
                                            [value],
                                            setAddedFiles,
                                            "remove",
                                        );
                                    }}
                                >
                                    <Check className="h-4 w-4 mr-2" />
                                    <span className="break-all">{filename}</span>
                                </CommandItem>
                            ) : (
                                <CommandItem
                                    key={filename}
                                    className="mb-1"
                                    value={filename}
                                    onSelect={(value) => {
                                        if (!usingConversationContext) return;

                                        modifyFileFilterForConversation(
                                            props.conversationId,
                                            [value],
                                            setAddedFiles,
                                            "add",
                                        );
                                    }}
                                >
                                    <span className="break-all">{filename}</span>
                                </CommandItem>
                            ),
                        )}
                    </CommandGroup>
                </CommandList>
            </Command>
        );
    };

    if (props.isMobileWidth) {
        return (
            <>
                <Drawer>
                    <DrawerTrigger className="bg-background border border-muted p-4 rounded-2xl my-8 text-left inline-flex items-center justify-between w-full">
                        Manage Files <ArrowRight className="h-4 w-4 mx-2" />
                    </DrawerTrigger>
                    <DrawerContent>
                        <DrawerHeader>
                            <DrawerTitle>Files</DrawerTitle>
                            <DrawerDescription>
                                {usingConversationContext
                                    ? "Manage files for this conversation"
                                    : "Shared files"}
                            </DrawerDescription>
                        </DrawerHeader>
                        <div className={`${styles.panelWrapper}`}>
                            <FilesMenuCommandBox />
                        </div>
                        <DrawerFooter>
                            <DrawerClose>
                                <Button variant="outline">Done</Button>
                            </DrawerClose>
                        </DrawerFooter>
                    </DrawerContent>
                </Drawer>
            </>
        );
    }

    return (
        <>
            <Popover open={isOpen} onOpenChange={setIsOpen}>
                <PopoverTrigger asChild>
                    <div className="w-auto bg-background border border-muted p-4 drop-shadow-sm rounded-2xl my-8">
                        <div className="flex items-center justify-between space-x-4">
                            <h4 className="text-sm font-semibold">
                                {usingConversationContext ? "Manage Context" : "Files"}
                                <p>
                                    {usingConversationContext ? (
                                        <span className="text-muted-foreground text-xs">
                                            Using{" "}
                                            {addedFiles.length == 0
                                                ? files.length
                                                : addedFiles.length}{" "}
                                            files
                                        </span>
                                    ) : (
                                        <span className="text-muted-foreground text-xs">
                                            Shared{" "}
                                            {addedFiles.length == 0
                                                ? files.length
                                                : addedFiles.length}{" "}
                                            files
                                        </span>
                                    )}
                                </p>
                            </h4>
                            <Button variant="ghost" size="sm" className="w-9 p-0">
                                {isOpen ? (
                                    <ArrowDown className="h-4 w-4" />
                                ) : (
                                    <ArrowRight className="h-4 w-4" />
                                )}
                                <span className="sr-only">Toggle</span>
                            </Button>
                        </div>
                    </div>
                </PopoverTrigger>
                <PopoverContent className={`mx-2`}>
                    <FilesMenuCommandBox />
                </PopoverContent>
            </Popover>
        </>
    );
}

interface SessionsAndFilesProps {
    subsetOrganizedData: GroupedChatHistory | null;
    organizedData: GroupedChatHistory | null;
    data: ChatHistory[] | null;
    userProfile: UserProfile | null;
    conversationId: string | null;
    uploadedFiles: string[];
    isMobileWidth: boolean;
    sideBarOpen: boolean;
}

function SessionsAndFiles(props: SessionsAndFilesProps) {
    return (
        <div>
            {props.sideBarOpen && (
                <ScrollArea>
                    <ScrollAreaScrollbar
                        orientation="vertical"
                        className="h-full w-2.5 border-l border-l-transparent p-[1px]"
                    />
                    <div className="p-0 m-0">
                        {props.subsetOrganizedData != null &&
                            Object.keys(props.subsetOrganizedData)
                                .filter((tg) => tg !== "All Time")
                                .map((timeGrouping) => (
                                    <div key={timeGrouping} className={`my-1`}>
                                        <div className={`text-muted-foreground text-xs p-[0.5rem]`}>
                                            {timeGrouping}
                                        </div>
                                        {props.subsetOrganizedData &&
                                            props.subsetOrganizedData[timeGrouping].map(
                                                (chatHistory) => (
                                                    <ChatSession
                                                        updated={chatHistory.updated}
                                                        created={chatHistory.created}
                                                        compressed={true}
                                                        key={chatHistory.conversation_id}
                                                        conversation_id={
                                                            chatHistory.conversation_id
                                                        }
                                                        slug={chatHistory.slug}
                                                        agent_name={chatHistory.agent_name}
                                                        agent_color={chatHistory.agent_color}
                                                        agent_icon={chatHistory.agent_icon}
                                                    />
                                                ),
                                            )}
                                    </div>
                                ))}
                    </div>
                </ScrollArea>
            )}
            {props.data && props.data.length > 5 && (
                <ChatSessionsModal data={props.organizedData} sideBarOpen={props.sideBarOpen} />
            )}
        </div>
    );
}

export interface ChatSessionActionMenuProps {
    conversationId: string;
    setTitle: (title: string) => void;
    sizing?: "sm" | "md" | "lg";
}

export function ChatSessionActionMenu(props: ChatSessionActionMenuProps) {
    const [renamedTitle, setRenamedTitle] = useState("");
    const [isRenaming, setIsRenaming] = useState(false);
    const [isSharing, setIsSharing] = useState(false);
    const [isDeleting, setIsDeleting] = useState(false);
    const [shareUrl, setShareUrl] = useState("");
    const [showShareUrl, setShowShareUrl] = useState(false);

    const [isOpen, setIsOpen] = useState(false);

    useEffect(() => {
        if (isSharing) {
            shareConversation(props.conversationId, setShareUrl);
            setShowShareUrl(true);
            setIsSharing(false);
        }
    }, [isSharing, props.conversationId]);

    if (isRenaming) {
        return (
            <Dialog open={isRenaming} onOpenChange={(open) => setIsRenaming(open)}>
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>Set a new title for the conversation</DialogTitle>
                        <DialogDescription>
                            This will help you identify the conversation easily, and also help you
                            search for it later.
                        </DialogDescription>
                        <Input
                            value={renamedTitle}
                            onChange={(e) => setRenamedTitle(e.target.value)}
                        />
                    </DialogHeader>
                    <DialogFooter>
                        <Button
                            onClick={() => {
                                renameConversation(props.conversationId, renamedTitle);
                                props.setTitle(renamedTitle);
                                setIsRenaming(false);
                            }}
                            type="submit"
                        >
                            Rename
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        );
    }

    if (isSharing || showShareUrl) {
        if (shareUrl) {
            navigator.clipboard.writeText(shareUrl);
        }
        return (
            <Dialog
                open={isSharing || showShareUrl}
                onOpenChange={(open) => {
                    setShowShareUrl(open);
                    setIsSharing(open);
                }}
            >
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>Conversation Share URL</DialogTitle>
                        <DialogDescription>
                            Sharing this chat session will allow anyone with a link to view the
                            conversation.
                            <Input
                                className="w-full bg-accent text-accent-foreground rounded-md p-2 mt-2"
                                value={shareUrl}
                                readOnly={true}
                            />
                        </DialogDescription>
                    </DialogHeader>
                    <DialogFooter>
                        {!showShareUrl && (
                            <Button
                                onClick={() => {
                                    shareConversation(props.conversationId, setShareUrl);
                                    setShowShareUrl(true);
                                }}
                                className="bg-orange-500"
                                disabled
                            >
                                <Spinner className="mr-2 h-4 w-4 animate-spin" />
                                Sharing
                            </Button>
                        )}
                        {showShareUrl && (
                            <Button
                                onClick={() => {
                                    navigator.clipboard.writeText(shareUrl);
                                }}
                                variant={"default"}
                            >
                                Copy
                            </Button>
                        )}
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        );
    }

    if (isDeleting) {
        return (
            <AlertDialog open={isDeleting} onOpenChange={(open) => setIsDeleting(open)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>Delete Conversation</AlertDialogTitle>
                        <AlertDialogDescription>
                            Are you sure you want to delete this conversation? This action cannot be
                            undone.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>Cancel</AlertDialogCancel>
                        <AlertDialogAction
                            onClick={() => {
                                deleteConversation(props.conversationId);
                                setIsDeleting(false);
                            }}
                            className="bg-rose-500 hover:bg-rose-600"
                        >
                            Delete
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        );
    }

    function sizeClass() {
        switch (props.sizing) {
            case "sm":
                return "h-4 w-4";
            case "md":
                return "h-6 w-6";
            case "lg":
                return "h-8 w-8";
            default:
                return "h-4 w-4";
        }
    }

    const size = sizeClass();

    return (
        <div className="flex items-center gap-2">
            {(props.sizing === "lg" || props.sizing === "md") && (
                <Button
                    className="p-0 text-sm h-auto"
                    variant={"ghost"}
                    onClick={() => setIsSharing(true)}
                >
                    <Share className={`${size}`} />
                </Button>
            )}
            <DropdownMenu onOpenChange={(open) => setIsOpen(open)} open={isOpen}>
                <DropdownMenuTrigger asChild>
                    {props.sizing === "lg" || props.sizing === "md" ? (
                        <Button className="p-0 text-sm h-auto" variant={"ghost"}>
                            <DotsThreeVertical className={`${size}`} />
                        </Button>
                    ) : (
                        <SidebarMenuAction asChild>
                            <DotsThreeVertical className={`${size}`} />
                        </SidebarMenuAction>
                    )}
                </DropdownMenuTrigger>
                <DropdownMenuContent side="right" align="start">
                    <DropdownMenuItem onClick={() => setIsRenaming(true)}>
                        <span className="flex items-center">
                            <Pencil className={`mr-2 ${size}`} />
                            Rename
                        </span>
                    </DropdownMenuItem>
                    {props.sizing === "sm" && (
                        <DropdownMenuItem onClick={() => setIsSharing(true)}>
                            <span className="flex items-center">
                                <Share className={`mr-2 ${size}`} />
                                Share
                            </span>
                        </DropdownMenuItem>
                    )}
                    <DropdownMenuItem onClick={() => setIsDeleting(true)}>
                        <span className="flex items-center">
                            <Trash className={`mr-2 ${size}`} />
                            Delete
                        </span>
                    </DropdownMenuItem>
                </DropdownMenuContent>
            </DropdownMenu>
        </div>
    );
}

function ChatSession(props: ChatHistory) {
    const [isHovered, setIsHovered] = useState(false);
    const [title, setTitle] = useState(props.slug || "New Conversation 🌱");
    var currConversationId =
        new URLSearchParams(window.location.search).get("conversationId") || "-1";
    return (
        <SidebarMenuItem
            onMouseEnter={() => setIsHovered(true)}
            onMouseLeave={() => setIsHovered(false)}
            key={props.conversation_id}
            className={`${styles.session} ${props.compressed ? styles.compressed : "!max-w-full"} ${isHovered ? `${styles.sessionHover}` : ""} ${currConversationId === props.conversation_id && currConversationId != "-1" ? "dark:bg-neutral-800 bg-white" : ""}`}
        >
            <SidebarMenuButton asChild>
                <Link
                    href={`/chat?conversationId=${props.conversation_id}`}
                    className="flex items-center gap-2 no-underline"
                >
                    <p
                        className={`${styles.session} ${props.compressed ? styles.compressed : styles.expanded}`}
                    >
                        {title}
                    </p>
                </Link>
            </SidebarMenuButton>
            <ChatSessionActionMenu
                conversationId={props.conversation_id}
                setTitle={setTitle}
                sizing="sm"
            />
        </SidebarMenuItem>
    );
}

interface ChatSessionsModalProps {
    data: GroupedChatHistory | null;
    sideBarOpen: boolean;
}

interface AgentStyle {
    color: string;
    icon: string;
}

function ChatSessionsModal({ data, sideBarOpen }: ChatSessionsModalProps) {
    const [agentsFilter, setAgentsFilter] = useState<string[]>([]);
    const [agentOptions, setAgentOptions] = useState<string[]>([]);
    const [searchQuery, setSearchQuery] = useState<string>("");

    const [agentNameToStyleMap, setAgentNameToStyleMap] = useState<Record<string, AgentStyle>>({});

    useEffect(() => {
        if (data) {
            const agents: string[] = [];
            let agentNameToStyleMapLocal: Record<string, AgentStyle> = {};
            Object.keys(data).forEach((timeGrouping) => {
                data[timeGrouping].forEach((chatHistory) => {
                    if (!agents.includes(chatHistory.agent_name) && chatHistory.agent_name) {
                        agents.push(chatHistory.agent_name);

                        agentNameToStyleMapLocal = {
                            ...agentNameToStyleMapLocal,
                            [chatHistory.agent_name]: {
                                color: chatHistory.agent_color,
                                icon: chatHistory.agent_icon,
                            },
                        };
                    }
                });
            });
            setAgentNameToStyleMap(agentNameToStyleMapLocal);
            setAgentOptions(agents);
        }
    }, [data]);

    // Memoize the filtered results
    const filteredData = useMemo(() => {
        if (!data) return null;

        // Early return if no filters active
        if (agentsFilter.length === 0 && searchQuery.length === 0) {
            return data;
        }

        const filtered: GroupedChatHistory = {};
        const agentSet = new Set(agentsFilter);
        const searchLower = searchQuery.toLowerCase();

        for (const timeGrouping in data) {
            const matches = data[timeGrouping].filter((chatHistory) => {
                // Early return for agent filter
                if (agentsFilter.length > 0 && !agentSet.has(chatHistory.agent_name)) {
                    return false;
                }

                // Early return for search query
                if (searchQuery && !chatHistory.slug?.toLowerCase().includes(searchLower)) {
                    return false;
                }

                return true;
            });

            if (matches.length > 0) {
                filtered[timeGrouping] = matches;
            }
        }

        return filtered;
    }, [data, agentsFilter, searchQuery]);

    return (
        <Dialog>
            <DialogTrigger
                className={`flex text-left text-medium text-gray-500 hover:text-gray-300 cursor-pointer my-1 text-sm ${sideBarOpen ? "p-[0.5rem] " : "p-[0.1rem]"}`}
            >
                <span className="flex items-center gap-1">
                    <ChatsCircle className="inline h-4 w-4 mr-1" />
                    {sideBarOpen ? "All Conversations" : ""}
                </span>
            </DialogTrigger>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>All Conversations</DialogTitle>
                    <DialogDescription className="p-0">
                        <div className="flex flex-row justify-between mt-2 gap-2">
                            <Input
                                value={searchQuery}
                                onChange={(e) => {
                                    setSearchQuery(e.target.value);
                                }}
                                placeholder="Search conversations"
                            />
                            <DropdownMenu>
                                <DropdownMenuTrigger asChild>
                                    <Button
                                        variant="ghost"
                                        className={`p-0 px-1 ${agentsFilter.length > 0 ? "bg-muted text-muted-foreground" : "bg-inherit"} `}
                                    >
                                        <FunnelSimple />
                                    </Button>
                                </DropdownMenuTrigger>
                                <DropdownMenuContent>
                                    <DropdownMenuLabel>Agents</DropdownMenuLabel>
                                    <DropdownMenuSeparator />
                                    {agentOptions.map((agent) => (
                                        <DropdownMenuCheckboxItem
                                            key={agent}
                                            onSelect={(e) => e.preventDefault()}
                                            checked={agentsFilter.includes(agent)}
                                            onCheckedChange={(checked) => {
                                                if (checked) {
                                                    setAgentsFilter([...agentsFilter, agent]);
                                                } else {
                                                    setAgentsFilter(
                                                        agentsFilter.filter((a) => a !== agent),
                                                    );
                                                }
                                            }}
                                        >
                                            <div className="flex items-center justify-center px-1">
                                                {getIconFromIconName(
                                                    agentNameToStyleMap[agent]?.icon,
                                                    agentNameToStyleMap[agent]?.color,
                                                )}
                                                <div className="break-words">{agent}</div>
                                            </div>
                                        </DropdownMenuCheckboxItem>
                                    ))}
                                </DropdownMenuContent>
                            </DropdownMenu>
                        </div>
                        <ScrollArea className="h-[500px] py-4">
                            {filteredData &&
                                Object.keys(filteredData).map((timeGrouping) => (
                                    <div key={timeGrouping}>
                                        <div
                                            className={`text-muted-foreground text-sm font-bold p-[0.5rem] `}
                                        >
                                            {timeGrouping}
                                        </div>
                                        {filteredData[timeGrouping].map((chatHistory) => (
                                            <ChatSession
                                                updated={chatHistory.updated}
                                                created={chatHistory.created}
                                                compressed={false}
                                                key={chatHistory.conversation_id}
                                                conversation_id={chatHistory.conversation_id}
                                                slug={chatHistory.slug}
                                                agent_name={chatHistory.agent_name}
                                                agent_color={chatHistory.agent_color}
                                                agent_icon={chatHistory.agent_icon}
                                            />
                                        ))}
                                    </div>
                                ))}
                        </ScrollArea>
                    </DialogDescription>
                </DialogHeader>
            </DialogContent>
        </Dialog>
    );
}

const fetchChatHistory = async (url: string) => {
    const response = await fetch(url, {
        method: "GET",
        headers: {
            "Content-Type": "application/json",
        },
    });
    return response.json();
};

export const useChatSessionsFetchRequest = (url: string) => {
    const { data, isLoading, error } = useSWR<ChatHistory[]>(url, fetchChatHistory);

    return { data, isLoading, error };
};

interface SidePanelProps {
    conversationId: string | null;
    uploadedFiles: string[];
    isMobileWidth: boolean;
    sideBarOpen: boolean;
}

export default function AllConversations(props: SidePanelProps) {
    const [data, setData] = useState<ChatHistory[] | null>(null);
    const [organizedData, setOrganizedData] = useState<GroupedChatHistory | null>(null);
    const [subsetOrganizedData, setSubsetOrganizedData] = useState<GroupedChatHistory | null>(null);

    const {
        data: authenticatedData,
        error: authenticationError,
        isLoading: authenticationLoading,
    } = useAuthenticatedData();
    const { data: chatSessions, isLoading } = useChatSessionsFetchRequest(
        authenticatedData ? `/api/chat/sessions` : "",
    );

    useEffect(() => {
        if (chatSessions) {
            setData(chatSessions);

            const groupedData: GroupedChatHistory = {};
            const subsetOrganizedData: GroupedChatHistory = {};
            let numAdded = 0;

            const currentDate = new Date();

            chatSessions.forEach((chatSessionMetadata) => {
                const chatDate = new Date(chatSessionMetadata.updated);
                const diffTime = Math.abs(currentDate.getTime() - chatDate.getTime());
                const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));

                const timeGrouping =
                    diffDays < 7 ? "Recent" : diffDays < 30 ? "Last Month" : "All Time";
                if (!groupedData[timeGrouping]) {
                    groupedData[timeGrouping] = [];
                }
                groupedData[timeGrouping].push(chatSessionMetadata);

                // Add to subsetOrganizedData if less than 8
                if (numAdded < 8) {
                    if (!subsetOrganizedData[timeGrouping]) {
                        subsetOrganizedData[timeGrouping] = [];
                    }
                    subsetOrganizedData[timeGrouping].push(chatSessionMetadata);
                    numAdded++;
                }
            });

            setSubsetOrganizedData(subsetOrganizedData);
            setOrganizedData(groupedData);
        }
    }, [chatSessions]);

    if (isLoading) {
        return (
            <SidebarGroup className="p-0 m-0">
                <SidebarGroupLabel className="!p-0 m-0 px-0">Conversations</SidebarGroupLabel>
                {Array.from({ length: 5 }).map((_, index) => (
                    <SidebarMenuItem key={index} className="p-0 list-none m-0">
                        <SidebarMenuSkeleton showIcon />
                    </SidebarMenuItem>
                ))}
            </SidebarGroup>
        );
    }

    return (
        <SidebarGroup>
            <div className={`flex justify-between flex-col`}>
                {authenticatedData && (
                    <>
                        <SidebarGroupLabel className="!p-0 m-0 px-0">
                            Conversations
                        </SidebarGroupLabel>
                        <div
                            className={`${props.sideBarOpen ? "border-l-2 border-light-blue-500 border-opacity-25 " : ""}`}
                        >
                            <SessionsAndFiles
                                subsetOrganizedData={subsetOrganizedData}
                                organizedData={organizedData}
                                data={data}
                                uploadedFiles={props.uploadedFiles}
                                userProfile={authenticatedData}
                                conversationId={props.conversationId}
                                isMobileWidth={props.isMobileWidth}
                                sideBarOpen={props.sideBarOpen}
                            />
                        </div>
                        {props.sideBarOpen && (
                            <FilesMenu
                                conversationId={props.conversationId}
                                uploadedFiles={props.uploadedFiles}
                                isMobileWidth={props.isMobileWidth}
                            />
                        )}
                    </>
                )}
            </div>
        </SidebarGroup>
    );
}
