"use client";

import styles from "./settings.module.css";
import "intl-tel-input/styles";

import { Suspense, useEffect, useState } from "react";
import { useToast } from "@/components/ui/use-toast";

import { useUserConfig, ModelOptions, UserConfig, SubscriptionStates, isUserSubscribed } from "../common/auth";
import { toTitleCase, useIsMobileWidth } from "../common/utils";

import { isValidPhoneNumber } from "libphonenumber-js";

import { Button } from "@/components/ui/button";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";

import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuRadioGroup,
    DropdownMenuRadioItem,
    DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
    AlertDialogTrigger,
} from "@/components/ui/alert-dialog";

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

import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table";

import {
    ArrowRight,
    ChatCircleText,
    Key,
    Palette,
    UserCircle,
    Trash,
    Copy,
    CreditCard,
    CheckCircle,
    NotionLogo,
    GithubLogo,
    Files,
    WhatsappLogo,
    ExclamationMark,
    Plugs,
    CloudSlash,
    Laptop,
    Plus,
    FloppyDisk,
    PlugsConnected,
    ArrowCircleUp,
    ArrowCircleDown,
    ArrowsClockwise,
    CaretDown,
    Waveform,
    MagnifyingGlass,
    Brain,
    EyeSlash,
    Eye,
    Download,
    TrashSimple,
} from "@phosphor-icons/react";

import Loading from "../components/loading/loading";

import IntlTelInput from "intl-tel-input/react";
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { AppSidebar } from "../components/appSidebar/appSidebar";
import { UserMemory, UserMemorySchema } from "../components/userMemory/userMemory";
import { Separator } from "@/components/ui/separator";
import { KhojLogoType } from "../components/logo/khojLogo";
import { Progress } from "@/components/ui/progress";

import JSZip from "jszip";
import { saveAs } from "file-saver";

interface DropdownComponentProps {
    items: ModelOptions[];
    selected: number;
    isActive?: boolean;
    callbackFunc: (value: string) => Promise<void>;
}

const DropdownComponent: React.FC<DropdownComponentProps> = ({
    items,
    selected,
    isActive,
    callbackFunc,
}) => {
    const [position, setPosition] = useState(selected?.toString() ?? "0");

    return (
        !!selected && (
            <div className="overflow-hidden shadow-md rounded-lg">
                <DropdownMenu>
                    <DropdownMenuTrigger asChild className="w-full rounded-lg">
                        <Button variant="outline" className="justify-start py-6 rounded-lg">
                            {items.find((item) => item.id.toString() === position)?.name}{" "}
                            <CaretDown className="h-4 w-4 ml-auto text-muted-foreground" />
                        </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent
                        style={{
                            maxHeight: "200px",
                            overflowY: "auto",
                            minWidth: "var(--radix-dropdown-menu-trigger-width)",
                        }}
                    >
                        <DropdownMenuRadioGroup
                            value={position}
                            onValueChange={async (value) => {
                                setPosition(value);
                                await callbackFunc(value);
                            }}
                        >
                            {items.map((item) => (
                                <DropdownMenuRadioItem
                                    key={item.id.toString()}
                                    value={item.id.toString()}
                                    disabled={!isActive && item.tier !== "free"}
                                >
                                    {item.name}{" "}
                                    {item.tier === "standard" && (
                                        <span className="text-green-500 ml-2">(Futurist)</span>
                                    )}
                                </DropdownMenuRadioItem>
                            ))}
                        </DropdownMenuRadioGroup>
                    </DropdownMenuContent>
                </DropdownMenu>
            </div>
        )
    );
};

interface TokenObject {
    token: string;
    name: string;
}

const useApiKeys = () => {
    const [apiKeys, setApiKeys] = useState<TokenObject[]>([]);
    const { toast } = useToast();

    const generateAPIKey = async () => {
        try {
            const response = await fetch(`/auth/token`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            const tokenObj = await response.json();
            setApiKeys((prevKeys) => [...prevKeys, tokenObj]);
        } catch (error) {
            console.error("Error generating API key:", error);
        }
    };

    const copyAPIKey = async (token: string) => {
        try {
            await navigator.clipboard.writeText(token);
            toast({
                title: "🔑 API Key",
                description: "Copied to clipboard",
            });
        } catch (error) {
            console.error("Error copying API key:", error);
        }
    };

    const deleteAPIKey = async (token: string) => {
        try {
            const response = await fetch(`/auth/token?token=${token}`, { method: "DELETE" });
            if (response.ok) {
                setApiKeys((prevKeys) => prevKeys.filter((key) => key.token !== token));
            }
        } catch (error) {
            console.error("Error deleting API key:", error);
        }
    };

    const listApiKeys = async () => {
        try {
            const response = await fetch(`/auth/token`);
            const tokens = await response.json();
            if (tokens?.length > 0) {
                setApiKeys(tokens);
            }
        } catch (error) {
            console.error("Error listing API keys:", error);
        }
    };

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

    return {
        apiKeys,
        generateAPIKey,
        copyAPIKey,
        deleteAPIKey,
    };
};

function ApiKeyCard() {
    const { apiKeys, generateAPIKey, copyAPIKey, deleteAPIKey } = useApiKeys();
    const [visibleApiKeys, setVisibleApiKeys] = useState<Set<string>>(new Set());
    const { toast } = useToast();

    return (
        <Card className="grid grid-flow-column border border-gray-300 shadow-md rounded-lg dark:bg-muted dark:border-none border-opacity-50 lg:w-2/3">
            <CardHeader className="text-xl grid grid-flow-col grid-cols-[1fr_auto] pb-0">
                <span className="flex flex-wrap">
                    <Key className="h-7 w-7 mr-2" />
                    API Keys
                </span>
                <Button variant="secondary" className="!mt-0" onClick={generateAPIKey}>
                    <Plus weight="bold" className="h-5 w-5 mr-2" />
                    Generate Key
                </Button>
            </CardHeader>
            <CardContent className="overflow-hidden grid gap-6">
                <p className="text-md text-gray-400">
                    Access Khoj from the{" "}
                    <a href="https://docs.khoj.dev/clients/desktop" target="_blank">
                        Desktop
                    </a>
                    , <a href="https://docs.khoj.dev/clients/obsidian">Obsidian</a>,{" "}
                    <a href="https://docs.khoj.dev/clients/emacs">Emacs</a> apps and more.
                </p>
                <Table>
                    <TableBody>
                        {apiKeys.map((key) => (
                            <TableRow key={key.token}>
                                <TableCell className="pl-0 py-3">{key.name}</TableCell>
                                <TableCell className="grid grid-flow-col grid-cols-[1fr_auto] bg-secondary dark:bg-background rounded-xl p-3 m-1">
                                    <span className="font-mono text-left w-[50px] md:w-[400px]">
                                        {visibleApiKeys.has(key.token)
                                            ? key.token
                                            : `${key.token.slice(0, 6)}...${key.token.slice(-4)}`}
                                    </span>
                                    <div className="grid grid-flow-col">
                                        {visibleApiKeys.has(key.token) ? (
                                            <EyeSlash
                                                weight="bold"
                                                className="h-4 w-4 mr-2 hover:bg-primary/40"
                                                onClick={() =>
                                                    setVisibleApiKeys((prev) => {
                                                        const next = new Set(prev);
                                                        next.delete(key.token);
                                                        return next;
                                                    })
                                                }
                                            />
                                        ) : (
                                            <Eye
                                                weight="bold"
                                                className="h-4 w-4 mr-2 hover:bg-primary/40"
                                                onClick={() =>
                                                    setVisibleApiKeys(
                                                        new Set([...visibleApiKeys, key.token]),
                                                    )
                                                }
                                            />
                                        )}
                                        <Copy
                                            weight="bold"
                                            className="h-4 w-4 mr-2 hover:bg-primary/40"
                                            onClick={() => {
                                                toast({
                                                    title: `🔑 Copied API Key: ${key.name}`,
                                                    description: `Set this API key in the Khoj apps you want to connect to this Khoj account`,
                                                });
                                                copyAPIKey(key.token);
                                            }}
                                        />
                                        <Trash
                                            weight="bold"
                                            className="h-4 w-4 mr-2 md:ml-4 text-red-400 hover:bg-primary/40"
                                            onClick={() => {
                                                toast({
                                                    title: `🔑 Deleted API Key: ${key.name}`,
                                                    description: `Apps using this API key will no longer connect to this Khoj account`,
                                                });
                                                deleteAPIKey(key.token);
                                            }}
                                        />
                                    </div>
                                </TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
            </CardContent>
            <CardFooter className="flex flex-wrap gap-4" />
        </Card>
    );
}

enum PhoneNumberValidationState {
    Setup = "setup",
    SendOTP = "otp",
    VerifyOTP = "verify",
    Verified = "verified",
}

export default function SettingsView() {
    const { data: initialUserConfig } = useUserConfig(true);
    const [userConfig, setUserConfig] = useState<UserConfig | null>(null);
    const [name, setName] = useState<string | undefined>(undefined);
    const [notionToken, setNotionToken] = useState<string | null>(null);
    const [phoneNumber, setPhoneNumber] = useState<string | undefined>(undefined);
    const [otp, setOTP] = useState("");
    const [numberValidationState, setNumberValidationState] = useState<PhoneNumberValidationState>(
        PhoneNumberValidationState.Verified,
    );
    const [memories, setMemories] = useState<UserMemorySchema[]>([]);
    const [enableMemory, setEnableMemory] = useState<boolean>(true);
    const [serverMemoryMode, setServerMemoryMode] = useState<string>("enabled_default_on");
    const [isExporting, setIsExporting] = useState(false);
    const [exportProgress, setExportProgress] = useState(0);
    const [exportedConversations, setExportedConversations] = useState(0);
    const [totalConversations, setTotalConversations] = useState(0);
    const { toast } = useToast();
    const isMobileWidth = useIsMobileWidth();

    const title = "Settings";

    const cardClassName =
        "w-full lg:w-5/12 grid grid-flow-column border border-gray-300 shadow-md rounded-lg border dark:border-none border-opacity-50 dark:bg-muted";

    useEffect(() => {
        setUserConfig(initialUserConfig);
        setPhoneNumber(initialUserConfig?.phone_number);
        setNumberValidationState(
            initialUserConfig?.is_phone_number_verified
                ? PhoneNumberValidationState.Verified
                : initialUserConfig?.phone_number
                  ? PhoneNumberValidationState.SendOTP
                  : PhoneNumberValidationState.Setup,
        );
        setName(initialUserConfig?.given_name);
        setNotionToken(initialUserConfig?.notion_token ?? null);
        setEnableMemory(initialUserConfig?.enable_memory ?? true);
        setServerMemoryMode(initialUserConfig?.server_memory_mode ?? "enabled_default_on");
    }, [initialUserConfig]);

    const sendOTP = async () => {
        try {
            const response = await fetch(`/api/phone?phone_number=${phoneNumber}`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error("Failed to send OTP");

            setNumberValidationState(PhoneNumberValidationState.VerifyOTP);
        } catch (error) {
            console.error("Error sending OTP:", error);
            toast({
                title: "📱 Phone",
                description: "Failed to send OTP. Try again or contact us at team@khoj.dev",
            });
        }
    };

    const verifyOTP = async () => {
        try {
            const response = await fetch(`/api/phone/verify?code=${otp}`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error("Failed to verify OTP");

            setNumberValidationState(PhoneNumberValidationState.Verified);
            toast({
                title: "📱 Phone",
                description: "Phone number verified",
            });
        } catch (error) {
            console.error("Error verifying OTP:", error);
            toast({
                title: "📱 Phone",
                description: "Failed to verify OTP. Try again or contact us at team@khoj.dev",
            });
        }
    };

    const disconnectNumber = async () => {
        try {
            const response = await fetch(`/api/phone`, {
                method: "DELETE",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error("Failed to disconnect phone number");

            setPhoneNumber(undefined);
            setNumberValidationState(PhoneNumberValidationState.Setup);
            toast({
                title: "📱 Phone",
                description: "Phone number disconnected",
            });
        } catch (error) {
            console.error("Error disconnecting phone number:", error);
            toast({
                title: "📱 Phone",
                description:
                    "Failed to disconnect phone number. Try again or contact us at team@khoj.dev",
            });
        }
    };

    const setSubscription = async (state: string) => {
        try {
            const url = `/api/subscription?operation=${state}`;
            const response = await fetch(url, {
                method: "PATCH",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error("Failed to change subscription");

            // Set updated user settings
            if (userConfig) {
                let newUserConfig = userConfig;
                newUserConfig.subscription_state =
                    state === "cancel"
                        ? SubscriptionStates.UNSUBSCRIBED
                        : SubscriptionStates.SUBSCRIBED;
                setUserConfig(newUserConfig);
            }

            // Notify user of subscription change
            toast({
                title: "💳 Subscription",
                description:
                    userConfig?.subscription_state === "unsubscribed"
                        ? "Your subscription was cancelled"
                        : "Your Futurist subscription has been renewed",
            });
        } catch (error) {
            console.error("Error changing subscription:", error);
            toast({
                title: "💳 Subscription",
                description:
                    state === "cancel"
                        ? "Failed to cancel subscription. Try again or contact us at team@khoj.dev"
                        : "Failed to renew subscription. Try again or contact us at team@khoj.dev",
            });
        }
    };

    const saveName = async () => {
        if (!name) return;
        try {
            const response = await fetch(`/api/user/name?name=${name}`, {
                method: "PATCH",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error("Failed to update name");

            // Set updated user settings
            if (userConfig) {
                let newUserConfig = userConfig;
                newUserConfig.given_name = name;
                setUserConfig(newUserConfig);
            }

            // Notify user of name change
            toast({
                title: `✅ Updated Profile`,
                description: `You name has been updated to ${name}`,
            });
        } catch (error) {
            console.error("Error updating name:", error);
            toast({
                title: "⚠️ Failed to Update Profile",
                description: "Failed to update name. Try again or contact team@khoj.dev",
            });
        }
    };

    const updateModel = (modelType: string) => async (id: string) => {
        // Get the selected model from the options
        const modelOptions =
            modelType === "chat"
                ? userConfig?.chat_model_options
                : modelType === "paint"
                  ? userConfig?.paint_model_options
                  : userConfig?.voice_model_options;

        const selectedModel = modelOptions?.find((model) => model.id.toString() === id);
        const modelName = selectedModel?.name;

        // Check if the model is free tier or if the user is active
        if (!userConfig?.is_active && selectedModel?.tier !== "free") {
            toast({
                title: `Model Update`,
                description: `Subscribe to switch ${modelType} model to ${modelName}.`,
                variant: "destructive",
            });
            return;
        }

        try {
            const response = await fetch(`/api/model/${modelType}?id=` + id, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
            });

            if (!response.ok)
                throw new Error(`Failed to switch ${modelType} model to ${modelName}`);

            toast({
                title: `✅ Switched ${modelType} model to ${modelName}`,
            });
        } catch (error) {
            console.error(`Failed to update ${modelType} model to ${modelName}:`, error);
            toast({
                description: `❌ Failed to switch ${modelType} model to ${modelName}. Try again.`,
                variant: "destructive",
            });
        }
    };

    const exportChats = async () => {
        try {
            setIsExporting(true);

            // Get total conversation count
            const statsResponse = await fetch("/api/chat/stats");
            const stats = await statsResponse.json();
            const total = stats.num_conversations;
            setTotalConversations(total);

            // Create zip file
            const zip = new JSZip();
            const conversations = [];

            // Fetch all conversations in batches of 10
            for (let page = 0; page * 10 < total; page++) {
                const response = await fetch(`/api/chat/export?page=${page}`);
                const data = await response.json();
                conversations.push(...data);

                setExportedConversations((page + 1) * 10);
                setExportProgress((((page + 1) * 10) / total) * 100);
            }

            // Add conversations to zip
            zip.file("conversations.json", JSON.stringify(conversations, null, 2));

            // Generate and download zip
            const content = await zip.generateAsync({ type: "blob" });
            saveAs(content, "khoj-conversations.zip");

            toast({
                title: "Export Complete",
                description: `Successfully exported ${conversations.length} conversations`,
            });
        } catch (error) {
            console.error("Error exporting chats:", error);
            toast({
                title: "Export Failed",
                description: "Failed to export chats. Please try again.",
                variant: "destructive",
            });
        } finally {
            setIsExporting(false);
            setExportProgress(0);
            setExportedConversations(0);
            setTotalConversations(0);
        }
    };

    const saveNotionToken = async () => {
        if (!notionToken) return;
        // Save Notion API key to server
        try {
            const response = await fetch(`/api/content/notion`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({ token: notionToken }),
            });
            if (!response.ok) throw new Error("Failed to save Notion API key");

            // Set updated user settings
            if (userConfig) {
                let newUserConfig = userConfig;
                newUserConfig.notion_token = notionToken;
                setUserConfig(newUserConfig);
            }

            // Notify user of Notion API key save
            toast({
                title: `✅ Saved Notion Settings`,
                description: `You Notion API key has been saved.`,
            });
        } catch (error) {
            console.error("Error updating name:", error);
            toast({
                title: "⚠️ Failed to Save Notion Settings",
                description: "Failed to save Notion API key. Try again or contact team@khoj.dev",
            });
        }
    };

    const fetchMemories = async () => {
        try {
            console.log("Fetching memories...");
            const response = await fetch('/api/memories');
            if (!response.ok) throw new Error('Failed to fetch memories');
            const data = await response.json();
            setMemories(data);
        } catch (error) {
            console.error('Error fetching memories:', error);
            toast({
                title: "Error",
                description: "Failed to fetch memories. Please try again.",
                variant: "destructive"
            });
        }
    };

    const handleDeleteMemory = async (id: number) => {
        try {
            const response = await fetch(`/api/memories/${id}`, {
                method: 'DELETE'
            });
            if (!response.ok) throw new Error('Failed to delete memory');
            setMemories(memories.filter(memory => memory.id !== id));
        } catch (error) {
            console.error('Error deleting memory:', error);
            toast({
                title: "Error",
                description: "Failed to delete memory. Please try again.",
                variant: "destructive"
            });
        }
    };

    const handleUpdateMemory = async (id: number, raw: string) => {
        try {
            const response = await fetch(`/api/memories/${id}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ raw, memory_id: id }),
            });
            if (!response.ok) throw new Error('Failed to update memory');
            const updatedMemory: UserMemorySchema = await response.json();
            setMemories(memories.map(memory =>
                memory.id === id ? updatedMemory : memory
            ));
        } catch (error) {
            console.error('Error updating memory:', error);
            toast({
                title: "Error",
                description: "Failed to update memory. Please try again.",
                variant: "destructive"
            });
        }
    };

    const handleToggleMemory = async (enabled: boolean) => {
        try {
            const response = await fetch(`/api/user/memory?enable_memory=${enabled}`, {
                method: 'PATCH',
            });
            if (!response.ok) throw new Error('Failed to update memory setting');
            setEnableMemory(enabled);
            toast({
                title: enabled ? "Memory enabled" : "Memory disabled",
                description: enabled
                    ? "Khoj will learn and remember from your conversations."
                    : "Khoj will no longer learn or remember from your conversations.",
            });
        } catch (error) {
            console.error('Error toggling memory:', error);
            toast({
                title: "Error",
                description: "Failed to update memory setting. Please try again.",
                variant: "destructive"
            });
        }
    };


    const syncContent = async (type: string) => {
        try {
            const response = await fetch(`/api/content?t=${type}`, {
                method: "PATCH",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error(`Failed to sync content from ${type}`);

            toast({
                title: `🔄 Syncing ${type}`,
                description: `Your ${type} content is being synced.`,
            });
        } catch (error) {
            console.error("Error syncing content:", error);
            toast({
                title: `⚠️ Failed to Sync ${type}`,
                description: `Failed to sync ${type} content. Try again or contact team@khoj.dev`,
            });
        }
    };

    const disconnectContent = async (source: string) => {
        try {
            const response = await fetch(`/api/content/source/${source}`, {
                method: "DELETE",
                headers: {
                    "Content-Type": "application/json",
                },
            });
            if (!response.ok) throw new Error(`Failed to disconnect ${source}`);

            // Set updated user settings
            if (userConfig) {
                let newUserConfig = userConfig;
                if (source === "computer") {
                    newUserConfig.enabled_content_source.computer = false;
                } else if (source === "notion") {
                    newUserConfig.enabled_content_source.notion = false;
                    newUserConfig.notion_token = null;
                    setNotionToken(newUserConfig.notion_token);
                } else if (source === "github") {
                    newUserConfig.enabled_content_source.github = false;
                }
                setUserConfig(newUserConfig);
            }

            // Notify user about disconnecting content source
            if (source === "computer") {
                toast({
                    title: `✅ Deleted Synced Files`,
                    description: "Your synced documents have been deleted.",
                });
            } else {
                toast({
                    title: `✅ Disconnected ${source}`,
                    description: `Your ${source} integration to Khoj has been disconnected.`,
                });
            }
        } catch (error) {
            console.error(`Error disconnecting ${source}:`, error);
            toast({
                title: `⚠️ Failed to Disconnect ${source}`,
                description: `Failed to disconnect from ${source}. Try again or contact team@khoj.dev`,
            });
        }
    };

    if (!userConfig) return <Loading />;

    return (
        <SidebarProvider>
            <AppSidebar conversationId={""} />
            <SidebarInset>
                <header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
                    <SidebarTrigger className="-ml-1" />
                    <Separator orientation="vertical" className="mr-2 h-4" />
                    {isMobileWidth ? (
                        <a className="p-0 no-underline" href="/">
                            <KhojLogoType className="h-auto w-16" />
                        </a>
                    ) : (
                        <h2 className="text-lg">Settings</h2>
                    )}
                </header>
                <div className={styles.page}>
                    <title>{title}</title>
                    <div className={styles.content}>
                        <div className={`${styles.contentBody} mx-10 my-2`}>
                            <Suspense fallback={<Loading />}>
                                <div
                                    id="content"
                                    className="grid grid-flow-column sm:grid-flow-row gap-16 m-8"
                                >
                                    <div className="section grid gap-8">
                                        <div className="text-2xl">Profile</div>
                                        <div className="cards flex flex-wrap gap-16">
                                            <Card className={cardClassName}>
                                                <CardHeader className="text-xl flex flex-row">
                                                    <UserCircle className="h-7 w-7 mr-2" />
                                                    Name
                                                </CardHeader>
                                                <CardContent className="overflow-hidden">
                                                    <p className="pb-4 text-gray-400">
                                                        What should Khoj refer to you as?
                                                    </p>
                                                    <Input
                                                        type="text"
                                                        onChange={(e) => setName(e.target.value)}
                                                        value={name || ""}
                                                        className="w-full border border-gray-300 rounded-lg p-4 py-6"
                                                    />
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    <Button
                                                        variant="outline"
                                                        size="sm"
                                                        onClick={saveName}
                                                        disabled={name === userConfig.given_name}
                                                    >
                                                        <FloppyDisk className="h-5 w-5 inline mr-2" />
                                                        Save
                                                    </Button>
                                                </CardFooter>
                                            </Card>
                                            {isUserSubscribed(userConfig) && (
                                            <Card id="subscription" className={cardClassName}>
                                                <CardHeader className="text-xl flex flex-row">
                                                    <CreditCard className="h-7 w-7 mr-2" />
                                                    Subscription
                                                </CardHeader>
                                                <CardContent className="grid gap-2 overflow-hidden">
                                                    <p className="text-gray-400">Current Plan</p>
                                                    {(userConfig.subscription_state === "trial" && (
                                                        <>
                                                            <p className="text-xl text-primary/80">
                                                                Futurist (Trial)
                                                            </p>
                                                            <p className="text-gray-400">
                                                                You are on a{" "}
                                                                {userConfig.length_of_free_trial}{" "}
                                                                day trial of the Khoj Futurist plan.
                                                                Your trial ends on{" "}
                                                                {
                                                                    userConfig.subscription_renewal_date
                                                                }
                                                                . Check{" "}
                                                                <a
                                                                    href="https://khoj.dev/#pricing"
                                                                    target="_blank"
                                                                >
                                                                    pricing page
                                                                </a>{" "}
                                                                to compare plans.
                                                            </p>
                                                        </>
                                                    )) ||
                                                        (userConfig.subscription_state ===
                                                            "subscribed" && (
                                                            <>
                                                                <p className="text-xl text-primary/80">
                                                                    Futurist
                                                                </p>
                                                                <p className="text-gray-400">
                                                                    Subscription <b>renews</b> on{" "}
                                                                    <b>
                                                                        {
                                                                            userConfig.subscription_renewal_date
                                                                        }
                                                                    </b>
                                                                </p>
                                                            </>
                                                        )) ||
                                                        (userConfig.subscription_state ===
                                                            "unsubscribed" && (
                                                            <>
                                                                <p className="text-xl">Futurist</p>
                                                                <p className="text-gray-400">
                                                                    Subscription <b>ends</b> on{" "}
                                                                    <b>
                                                                        {
                                                                            userConfig.subscription_renewal_date
                                                                        }
                                                                    </b>
                                                                </p>
                                                            </>
                                                        ))}
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    {(userConfig.subscription_state ==
                                                        "subscribed" && (
                                                        <Button
                                                            variant="outline"
                                                            className="hover:text-red-400"
                                                            onClick={() =>
                                                                setSubscription("cancel")
                                                            }
                                                        >
                                                            <ArrowCircleDown className="h-5 w-5 mr-2" />
                                                            Unsubscribe
                                                        </Button>
                                                    )) ||
                                                        (userConfig.subscription_state ==
                                                            "unsubscribed" && (
                                                            <Button
                                                                variant="outline"
                                                                className="text-primary/80 hover:text-primary"
                                                                onClick={() =>
                                                                    setSubscription("resubscribe")
                                                                }
                                                            >
                                                                <ArrowCircleUp
                                                                    weight="bold"
                                                                    className="h-5 w-5 mr-2"
                                                                />
                                                                Resubscribe
                                                            </Button>
                                                        )) ||
                                                        (
                                                            <Button
                                                                variant="outline"
                                                                className="text-primary/80 hover:text-primary"
                                                                onClick={() =>
                                                                    window.open(
                                                                        `${userConfig.khoj_cloud_subscription_url}?prefilled_email=${userConfig.username}`,
                                                                        "_blank",
                                                                        "noopener,noreferrer",
                                                                    )
                                                                }
                                                            >
                                                                <ArrowCircleUp
                                                                    weight="bold"
                                                                    className="h-5 w-5 mr-2"
                                                                />
                                                                Subscribe
                                                            </Button>
                                                        )}
                                                </CardFooter>
                                            </Card>
                                            )}
                                        </div>
                                    </div>
                                    <div className="section grid gap-8">
                                        <div className="text-2xl">Content</div>
                                        <div className="cards flex flex-wrap gap-16">
                                            <Card id="computer" className={cardClassName}>
                                                <CardHeader className="flex flex-row text-xl">
                                                    <Brain className="h-8 w-8 mr-2" />
                                                    Knowledge Base
                                                    {userConfig.enabled_content_source.computer && (
                                                        <CheckCircle
                                                            className="h-6 w-6 ml-auto text-green-500"
                                                            weight="fill"
                                                        />
                                                    )}
                                                </CardHeader>
                                                <CardContent className="overflow-hidden pb-12 text-gray-400">
                                                    Manage and search through your digital brain.
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    <Button
                                                        variant="outline"
                                                        size="sm"
                                                        title="Search thorugh files"
                                                        onClick={() =>
                                                            (window.location.href = "/search")
                                                        }
                                                    >
                                                        <MagnifyingGlass className="h-5 w-5 inline mr-1" />
                                                        Search
                                                    </Button>
                                                    <Button
                                                        variant="outline"
                                                        size="sm"
                                                        className={`${userConfig.enabled_content_source.computer || "hidden"}`}
                                                        onClick={() =>
                                                            disconnectContent("computer")
                                                        }
                                                    >
                                                        <CloudSlash className="h-5 w-5 inline mr-1" />
                                                        Clear All
                                                    </Button>
                                                </CardFooter>
                                            </Card>
                                            <Card id="github" className={`${cardClassName} hidden`}>
                                                <CardHeader className="flex flex-row text-2xl">
                                                    <GithubLogo className="h-8 w-8 mr-2" />
                                                    Github
                                                </CardHeader>
                                                <CardContent className="overflow-hidden pb-12 text-gray-400">
                                                    Set Github repositories to index
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    <Button variant="outline" size="sm">
                                                        {(userConfig.enabled_content_source
                                                            .github && (
                                                            <>
                                                                <Files className="h-5 w-5 inline mr-1" />
                                                                Manage
                                                            </>
                                                        )) || (
                                                            <>
                                                                <Plugs className="h-5 w-5 inline mr-1" />
                                                                Connect
                                                            </>
                                                        )}
                                                    </Button>
                                                    <Button
                                                        variant="outline"
                                                        size="sm"
                                                        className={`${userConfig.enabled_content_source.github || "hidden"}`}
                                                    >
                                                        <CloudSlash className="h-5 w-5 inline mr-1" />
                                                        Disable
                                                    </Button>
                                                </CardFooter>
                                            </Card>
                                            <Card id="notion" className={cardClassName}>
                                                <CardHeader className="text-xl flex flex-row">
                                                    <NotionLogo className="h-7 w-7 mr-2" />
                                                    Notion
                                                    {userConfig.enabled_content_source.notion && (
                                                        <CheckCircle
                                                            className="h-6 w-6 ml-auto text-green-500"
                                                            weight="fill"
                                                        />
                                                    )}
                                                </CardHeader>
                                                <CardContent className="grid gap-4">
                                                    <p className="text-gray-400">
                                                        Sync your Notion workspace.
                                                    </p>
                                                    {!userConfig.notion_oauth_url && (
                                                        <Input
                                                            onChange={(e) =>
                                                                setNotionToken(e.target.value)
                                                            }
                                                            value={notionToken || ""}
                                                            placeholder="Enter API Key of your Khoj integration on Notion"
                                                            className="w-full border border-gray-300 rounded-lg px-4 py-6"
                                                        />
                                                    )}
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    {
                                                        /* Show connect to notion button if notion oauth url setup and user disconnected*/
                                                        userConfig.notion_oauth_url &&
                                                        !userConfig.enabled_content_source
                                                            .notion ? (
                                                            <Button
                                                                variant="outline"
                                                                size="sm"
                                                                onClick={() => {
                                                                    window.open(
                                                                        userConfig.notion_oauth_url,
                                                                    );
                                                                }}
                                                            >
                                                                <Plugs className="h-5 w-5 inline mr-1" />
                                                                Connect
                                                            </Button>
                                                        ) : /* Show sync button if user connected to notion and API key unchanged */
                                                        userConfig.enabled_content_source.notion &&
                                                          notionToken ===
                                                              userConfig.notion_token ? (
                                                            <Button
                                                                variant="outline"
                                                                size="sm"
                                                                onClick={() =>
                                                                    syncContent("notion")
                                                                }
                                                            >
                                                                <ArrowsClockwise className="h-5 w-5 inline mr-1" />
                                                                Sync
                                                            </Button>
                                                        ) : /* Show set API key button notion oauth url not set setup */
                                                        !userConfig.notion_oauth_url ? (
                                                            <Button
                                                                variant="outline"
                                                                size="sm"
                                                                onClick={saveNotionToken}
                                                                disabled={
                                                                    notionToken ===
                                                                    userConfig.notion_token
                                                                }
                                                            >
                                                                <FloppyDisk className="h-5 w-5 inline mr-1" />
                                                                {(userConfig.enabled_content_source
                                                                    .notion &&
                                                                    "Update API Key") ||
                                                                    "Set API Key"}
                                                            </Button>
                                                        ) : (
                                                            <></>
                                                        )
                                                    }
                                                    <Button
                                                        variant="outline"
                                                        size="sm"
                                                        className={`${userConfig.notion_token || "hidden"}`}
                                                        onClick={() => disconnectContent("notion")}
                                                    >
                                                        <CloudSlash className="h-5 w-5 inline mr-1" />
                                                        Disconnect
                                                    </Button>
                                                </CardFooter>
                                            </Card>
                                        </div>
                                    </div>
                                    <div className="section grid gap-8">
                                        <div className="text-2xl">Models</div>
                                        <div className="cards flex flex-wrap gap-16">
                                            {userConfig.chat_model_options.length > 0 && (
                                                <Card className={cardClassName}>
                                                    <CardHeader className="text-xl flex flex-row">
                                                        <ChatCircleText className="h-7 w-7 mr-2" />
                                                        Chat
                                                    </CardHeader>
                                                    <CardContent className="overflow-hidden pb-12 grid gap-8 h-fit">
                                                        <p className="text-gray-400">
                                                            Pick the chat model to generate text
                                                            responses
                                                        </p>
                                                        <DropdownComponent
                                                            items={userConfig.chat_model_options}
                                                            selected={
                                                                userConfig.selected_chat_model_config
                                                            }
                                                            isActive={userConfig.is_active}
                                                            callbackFunc={updateModel("chat")}
                                                        />
                                                    </CardContent>
                                                    <CardFooter className="flex flex-wrap gap-4">
                                                        {!userConfig.is_active && (
                                                            <p className="text-gray-400">
                                                                {userConfig.chat_model_options.some(
                                                                    (model) =>
                                                                        model.tier === "free",
                                                                )
                                                                    ? "Free models available"
                                                                    : "Subscribe to switch model"}
                                                            </p>
                                                        )}
                                                    </CardFooter>
                                                </Card>
                                            )}
                                            {userConfig.paint_model_options.length > 0 && (
                                                <Card className={cardClassName}>
                                                    <CardHeader className="text-xl flex flex-row">
                                                        <Palette className="h-7 w-7 mr-2" />
                                                        Paint
                                                    </CardHeader>
                                                    <CardContent className="overflow-hidden pb-12 grid gap-8 h-fit">
                                                        <p className="text-gray-400">
                                                            Pick the paint model to generate image
                                                            responses
                                                        </p>
                                                        <DropdownComponent
                                                            items={userConfig.paint_model_options}
                                                            selected={
                                                                userConfig.selected_paint_model_config
                                                            }
                                                            isActive={userConfig.is_active}
                                                            callbackFunc={updateModel("paint")}
                                                        />
                                                    </CardContent>
                                                    <CardFooter className="flex flex-wrap gap-4">
                                                        {!userConfig.is_active && (
                                                            <p className="text-gray-400">
                                                                {userConfig.paint_model_options.some(
                                                                    (model) =>
                                                                        model.tier === "free",
                                                                )
                                                                    ? "Free models available"
                                                                    : "Subscribe to switch model"}
                                                            </p>
                                                        )}
                                                    </CardFooter>
                                                </Card>
                                            )}
                                            {userConfig.voice_model_options.length > 0 && (
                                                <Card className={cardClassName}>
                                                    <CardHeader className="text-xl flex flex-row">
                                                        <Waveform className="h-7 w-7 mr-2" />
                                                        Voice
                                                    </CardHeader>
                                                    <CardContent className="overflow-hidden pb-12 grid gap-8 h-fit">
                                                        <p className="text-gray-400">
                                                            Pick the voice model to generate speech
                                                            responses
                                                        </p>
                                                        <DropdownComponent
                                                            items={userConfig.voice_model_options}
                                                            selected={
                                                                userConfig.selected_voice_model_config
                                                            }
                                                            isActive={userConfig.is_active}
                                                            callbackFunc={updateModel("voice")}
                                                        />
                                                    </CardContent>
                                                    <CardFooter className="flex flex-wrap gap-4">
                                                        {!userConfig.is_active && (
                                                            <p className="text-gray-400">
                                                                {userConfig.voice_model_options.some(
                                                                    (model) =>
                                                                        model.tier === "free",
                                                                )
                                                                    ? "Free models available"
                                                                    : "Subscribe to switch model"}
                                                            </p>
                                                        )}
                                                    </CardFooter>
                                                </Card>
                                            )}
                                        </div>
                                    </div>
                                    <div className="section grid gap-8">
                                        <div id="clients" className="text-2xl">
                                            Clients
                                        </div>
                                        <div className="cards flex flex-col flex-wrap gap-8">
                                            {!userConfig.anonymous_mode && <ApiKeyCard />}
                                        </div>
                                    </div>
                                    <div className="section grid gap-8">
                                        <div id="clients" className="text-2xl">
                                            Account
                                        </div>
                                        <div className="cards flex flex-wrap gap-16">
                                            <Card className={cardClassName}>
                                                <CardHeader className="text-xl flex flex-row">
                                                    <Download className="h-7 w-7 mr-2" />
                                                    Export Data
                                                </CardHeader>
                                                <CardContent className="overflow-hidden">
                                                    <p className="pb-4 text-gray-400">
                                                        Download all your chat conversations
                                                    </p>
                                                    {exportProgress > 0 && (
                                                        <div className="w-full mt-4">
                                                            <Progress
                                                                value={exportProgress}
                                                                className="w-full"
                                                            />
                                                            <p className="text-sm text-gray-500 mt-2">
                                                                Exported {exportedConversations} of{" "}
                                                                {totalConversations} conversations
                                                            </p>
                                                        </div>
                                                    )}
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    <Button
                                                        variant="outline"
                                                        onClick={exportChats}
                                                        disabled={isExporting}
                                                    >
                                                        <Download className="h-5 w-5 mr-2" />
                                                        {isExporting
                                                            ? "Exporting..."
                                                            : "Export Chats"}
                                                    </Button>
                                                </CardFooter>
                                            </Card>
                                            <Card className={cardClassName}>
                                                <CardHeader className="text-xl flex flex-row">
                                                    <Brain className="h-7 w-7 mr-2" />
                                                    Memories
                                                </CardHeader>
                                                <CardContent className="overflow-hidden">
                                                    <p className="pb-4 text-gray-400">
                                                        View and manage your long-term memories
                                                    </p>
                                                    <div className="flex items-center justify-between">
                                                        <label
                                                            htmlFor="enable-memory"
                                                            className={`text-sm font-medium leading-none ${serverMemoryMode === "disabled" ? "text-gray-400" : ""}`}
                                                        >
                                                            Enable Memory
                                                        </label>
                                                        <Switch
                                                            id="enable-memory"
                                                            checked={enableMemory}
                                                            onCheckedChange={(checked) => handleToggleMemory(checked)}
                                                            disabled={serverMemoryMode === "disabled"}
                                                        />
                                                    </div>
                                                    {serverMemoryMode === "disabled" && (
                                                        <p className="text-xs text-gray-400 mt-2">
                                                            Memory has been disabled by the server administrator.
                                                        </p>
                                                    )}
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    <Dialog onOpenChange={(open) => open && fetchMemories()}>
                                                        <DialogTrigger asChild>
                                                            <Button variant="outline">
                                                                <Brain className="h-5 w-5 mr-2" />
                                                                Browse Memories
                                                            </Button>
                                                        </DialogTrigger>
                                                        <DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
                                                            <DialogHeader>
                                                                <DialogTitle>Your Memories</DialogTitle>
                                                            </DialogHeader>
                                                            <div className="grid gap-4 py-4">
                                                                {memories.map((memory) => (
                                                                    <UserMemory
                                                                        key={memory.id}
                                                                        memory={memory}
                                                                        onDelete={handleDeleteMemory}
                                                                        onUpdate={handleUpdateMemory}
                                                                    />
                                                                ))}
                                                                {memories.length === 0 && (
                                                                    <p className="text-center text-gray-500">No memories found</p>
                                                                )}
                                                            </div>
                                                        </DialogContent>
                                                    </Dialog>
                                                </CardFooter>
                                            </Card>
                                            <Card className={cardClassName}>
                                                <CardHeader className="text-xl flex flex-row">
                                                    <TrashSimple className="h-7 w-7 mr-2 text-red-500" />
                                                    Delete Account
                                                </CardHeader>
                                                <CardContent className="overflow-hidden">
                                                    <p className="pb-4 text-gray-400">
                                                        This will delete all your account data,
                                                        including conversations, agents, and any
                                                        assets you{"'"}ve generated. Be sure to
                                                        export before you do this if you want to
                                                        keep your information.
                                                    </p>
                                                </CardContent>
                                                <CardFooter className="flex flex-wrap gap-4">
                                                    <AlertDialog>
                                                        <AlertDialogTrigger asChild>
                                                            <Button
                                                                variant="outline"
                                                                className="text-red-500 hover:text-red-600 hover:bg-red-50"
                                                            >
                                                                <TrashSimple className="h-5 w-5 mr-2" />
                                                                Delete Account
                                                            </Button>
                                                        </AlertDialogTrigger>
                                                        <AlertDialogContent>
                                                            <AlertDialogHeader>
                                                                <AlertDialogTitle>
                                                                    Are you absolutely sure?
                                                                </AlertDialogTitle>
                                                                <AlertDialogDescription>
                                                                    This action is irreversible.
                                                                    This will permanently delete
                                                                    your account and remove all your
                                                                    data from our servers.
                                                                </AlertDialogDescription>
                                                            </AlertDialogHeader>
                                                            <AlertDialogFooter>
                                                                <AlertDialogCancel>
                                                                    Cancel
                                                                </AlertDialogCancel>
                                                                <AlertDialogAction
                                                                    className="bg-red-500 hover:bg-red-600"
                                                                    onClick={async () => {
                                                                        try {
                                                                            const response =
                                                                                await fetch(
                                                                                    "/api/self",
                                                                                    {
                                                                                        method: "DELETE",
                                                                                    },
                                                                                );
                                                                            if (!response.ok)
                                                                                throw new Error(
                                                                                    "Failed to delete account",
                                                                                );

                                                                            toast({
                                                                                title: "Account Deleted",
                                                                                description:
                                                                                    "Your account has been successfully deleted.",
                                                                            });

                                                                            // Redirect to home page after successful deletion
                                                                            window.location.href =
                                                                                "/";
                                                                        } catch (error) {
                                                                            console.error(
                                                                                "Error deleting account:",
                                                                                error,
                                                                            );
                                                                            toast({
                                                                                title: "Error",
                                                                                description:
                                                                                    "Failed to delete account. Please try again or contact support.",
                                                                                variant:
                                                                                    "destructive",
                                                                            });
                                                                        }
                                                                    }}
                                                                >
                                                                    <TrashSimple className="h-5 w-5 mr-2" />
                                                                    Delete Account
                                                                </AlertDialogAction>
                                                            </AlertDialogFooter>
                                                        </AlertDialogContent>
                                                    </AlertDialog>
                                                </CardFooter>
                                            </Card>
                                        </div>
                                    </div>
                                </div>
                            </Suspense>
                        </div>
                    </div>
                </div>
            </SidebarInset>
        </SidebarProvider>
    );
}
