"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { flushSync } from "react-dom";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Trash2 } from "lucide-react";
import { Chat } from "@/components/chat-playground/chat";
import { type Message } from "@/components/chat-playground/chat-message";
import { VectorDBCreator } from "@/components/chat-playground/vector-db-creator";
import { useAuthClient } from "@/hooks/use-auth-client";
import type { Model } from "llama-stack-client/resources/models";
import type { TurnCreateParams } from "llama-stack-client/resources/agents/turn";
import {
  SessionUtils,
  type ChatSession,
} from "@/components/chat-playground/conversations";
import {
  cleanMessageContent,
  extractCleanText,
} from "@/lib/message-content-utils";
export default function ChatPlaygroundPage() {
  const [currentSession, setCurrentSession] = useState<ChatSession | null>(
    null
  );
  const [input, setInput] = useState("");
  const [isGenerating, setIsGenerating] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [models, setModels] = useState<Model[]>([]);
  const [selectedModel, setSelectedModel] = useState<string>("");
  const [modelsLoading, setModelsLoading] = useState(true);
  const [modelsError, setModelsError] = useState<string | null>(null);
  const [agents, setAgents] = useState<
    Array<{
      agent_id: string;
      agent_config?: {
        agent_name?: string;
        name?: string;
        instructions?: string;
      };
      [key: string]: unknown;
    }>
  >([]);
  const [selectedAgentConfig, setSelectedAgentConfig] = useState<{
    toolgroups?: Array<
      string | { name: string; args: Record<string, unknown> }
    >;
  } | null>(null);
  const [selectedAgentId, setSelectedAgentId] = useState<string>("");
  const [agentsLoading, setAgentsLoading] = useState(true);
  const [showCreateAgent, setShowCreateAgent] = useState(false);
  const [newAgentName, setNewAgentName] = useState("");
  const [newAgentInstructions, setNewAgentInstructions] = useState(
    "You are a helpful assistant."
  );
  const [selectedToolgroups, setSelectedToolgroups] = useState<string[]>([]);
  const [availableToolgroups, setAvailableToolgroups] = useState<
    Array<{
      identifier: string;
      provider_id: string;
      type: string;
      provider_resource_id?: string;
    }>
  >([]);
  const [showCreateVectorDB, setShowCreateVectorDB] = useState(false);
  const [availableVectorDBs, setAvailableVectorDBs] = useState<
    Array<{
      identifier: string;
      vector_db_name?: string;
      embedding_model: string;
    }>
  >([]);
  const [uploadNotification, setUploadNotification] = useState<{
    show: boolean;
    message: string;
    type: "success" | "error" | "loading";
  }>({ show: false, message: "", type: "success" });
  const [selectedVectorDBs, setSelectedVectorDBs] = useState<string[]>([]);
  const client = useAuthClient();
  const abortControllerRef = useRef<AbortController | null>(null);

  const isModelsLoading = modelsLoading ?? true;

  const loadAgentConfig = useCallback(
    async (agentId: string) => {
      try {
        // try to load from cache first
        const cachedConfig = SessionUtils.loadAgentConfig(agentId);
        if (cachedConfig) {
          setSelectedAgentConfig({
            toolgroups: cachedConfig.toolgroups,
          });
          return;
        }

        const agentDetails = await client.agents.retrieve(agentId);

        // cache config
        SessionUtils.saveAgentConfig(agentId, {
          ...agentDetails.agent_config,
          toolgroups: agentDetails.agent_config?.toolgroups,
        });

        setSelectedAgentConfig({
          toolgroups: agentDetails.agent_config?.toolgroups,
        });
      } catch (error) {
        console.error("Error loading agent config:", error);
        setSelectedAgentConfig(null);
      }
    },
    [client]
  );

  const createDefaultSession = useCallback(
    async (agentId: string) => {
      try {
        const response = await client.agents.session.create(agentId, {
          session_name: "Default Session",
        });

        const defaultSession: ChatSession = {
          id: response.session_id,
          name: "Default Session",
          messages: [],
          selectedModel: selectedModel, // use current selected model
          systemMessage: "You are a helpful assistant.",
          agentId,
          createdAt: Date.now(),
          updatedAt: Date.now(),
        };

        setCurrentSession(defaultSession);
        SessionUtils.saveCurrentSessionId(defaultSession.id, agentId);
        // cache entire session data
        SessionUtils.saveSessionData(agentId, defaultSession);
      } catch (error) {
        console.error("Error creating default session:", error);
      }
    },
    [client, selectedModel]
  );

  const loadSessionMessages = useCallback(
    async (agentId: string, sessionId: string): Promise<Message[]> => {
      try {
        const session = await client.agents.session.retrieve(
          agentId,
          sessionId
        );

        if (!session || !session.turns || !Array.isArray(session.turns)) {
          return [];
        }

        const messages: Message[] = [];
        for (const turn of session.turns) {
          if (turn.input_messages && Array.isArray(turn.input_messages)) {
            for (const input of turn.input_messages) {
              if (input.role === "user" && input.content) {
                messages.push({
                  id: `${turn.turn_id}-user-${messages.length}`,
                  role: "user",
                  content:
                    typeof input.content === "string"
                      ? input.content
                      : JSON.stringify(input.content),
                  createdAt: new Date(turn.started_at || Date.now()),
                });
              }
            }
          }

          if (turn.output_message && turn.output_message.content) {
            console.log("Raw message content:", turn.output_message.content);
            console.log("Content type:", typeof turn.output_message.content);

            const cleanContent = cleanMessageContent(
              turn.output_message.content
            );

            messages.push({
              id: `${turn.turn_id}-assistant-${messages.length}`,
              role: "assistant",
              content: cleanContent,
              createdAt: new Date(
                turn.completed_at || turn.started_at || Date.now()
              ),
            });
          }
        }

        return messages;
      } catch (error) {
        console.error("Error loading session messages:", error);
        return [];
      }
    },
    [client]
  );

  const loadAgentSessions = useCallback(
    async (agentId: string) => {
      try {
        const response = await client.agents.session.list(agentId);

        if (
          response.data &&
          Array.isArray(response.data) &&
          response.data.length > 0
        ) {
          // check for saved session ID for this agent
          const savedSessionId = SessionUtils.loadCurrentSessionId(agentId);
          // try to load cached agent session data first
          if (savedSessionId) {
            const cachedSession = SessionUtils.loadSessionData(
              agentId,
              savedSessionId
            );
            if (cachedSession) {
              setCurrentSession(cachedSession);
              SessionUtils.saveCurrentSessionId(cachedSession.id, agentId);
              return;
            }
            console.log("📡 Cache miss, fetching session from API...");
          }

          let sessionToLoad = response.data[0] as {
            session_id: string;
            session_name?: string;
            started_at?: string;
          };
          console.log(
            "Default session to load (first in list):",
            sessionToLoad.session_id
          );

          // try to find saved session id in available sessions
          if (savedSessionId) {
            const foundSession = response.data.find(
              (s: { [key: string]: unknown }) =>
                (s as { session_id: string }).session_id === savedSessionId
            );
            console.log("Found saved session in list:", foundSession);
            if (foundSession) {
              sessionToLoad = foundSession as {
                session_id: string;
                session_name?: string;
                started_at?: string;
              };
              console.log(
                "✅ Restored previously selected session:",
                savedSessionId
              );
            } else {
              console.log(
                "❌ Previously selected session not found, using latest session"
              );
            }
          } else {
            console.log("❌ No saved session ID found, using latest session");
          }

          const messages = await loadSessionMessages(
            agentId,
            sessionToLoad.session_id
          );

          const session: ChatSession = {
            id: sessionToLoad.session_id,
            name: sessionToLoad.session_name || "Session",
            messages,
            selectedModel: selectedModel || "",
            systemMessage: "You are a helpful assistant.",
            agentId,
            createdAt: sessionToLoad.started_at
              ? new Date(sessionToLoad.started_at).getTime()
              : Date.now(),
            updatedAt: Date.now(),
          };

          setCurrentSession(session);
          console.log(`💾 Saving session ID for agent ${agentId}:`, session.id);
          SessionUtils.saveCurrentSessionId(session.id, agentId);
          // cache session data
          SessionUtils.saveSessionData(agentId, session);
        } else {
          // no sessions, create a new one
          await createDefaultSession(agentId);
        }
      } catch (error) {
        console.error("Error loading agent sessions:", error);
        // fallback to creating a new session
        await createDefaultSession(agentId);
      }
    },
    [client, loadSessionMessages, createDefaultSession, selectedModel]
  );

  useEffect(() => {
    const fetchAgents = async () => {
      try {
        setAgentsLoading(true);
        const agentList = await client.agents.list();
        setAgents(
          (agentList.data as Array<{
            agent_id: string;
            agent_config?: {
              agent_name?: string;
              name?: string;
              instructions?: string;
            };
            [key: string]: unknown;
          }>) || []
        );

        if (agentList.data && agentList.data.length > 0) {
          // check if there's a previously selected agent
          const savedAgentId = SessionUtils.loadCurrentAgentId();

          let agentToSelect = agentList.data[0] as {
            agent_id: string;
            agent_config?: {
              agent_name?: string;
              name?: string;
              instructions?: string;
            };
            [key: string]: unknown;
          };

          // if we have a saved agent ID, find it in the available agents
          if (savedAgentId) {
            const foundAgent = agentList.data.find(
              (a: { [key: string]: unknown }) =>
                (a as { agent_id: string }).agent_id === savedAgentId
            );
            if (foundAgent) {
              agentToSelect = foundAgent as typeof agentToSelect;
            } else {
              console.log("Previously slelected agent not found:");
            }
          }
          setSelectedAgentId(agentToSelect.agent_id);
          SessionUtils.saveCurrentAgentId(agentToSelect.agent_id);
          // load agent config immediately
          await loadAgentConfig(agentToSelect.agent_id);
          // Note: loadAgentSessions will be called after models are loaded
        }
      } catch (error) {
        console.error("Error fetching agents:", error);
      } finally {
        setAgentsLoading(false);
      }
    };

    fetchAgents();

    const fetchToolgroups = async () => {
      try {
        const toolgroups = await client.toolgroups.list();

        const toolGroupsArray = Array.isArray(toolgroups)
          ? toolgroups
          : toolgroups &&
              typeof toolgroups === "object" &&
              "data" in toolgroups &&
              Array.isArray((toolgroups as { data: unknown }).data)
            ? (
                toolgroups as {
                  data: Array<{
                    identifier: string;
                    provider_id: string;
                    type: string;
                    provider_resource_id?: string;
                  }>;
                }
              ).data
            : [];

        if (toolGroupsArray && Array.isArray(toolGroupsArray)) {
          setAvailableToolgroups(toolGroupsArray);
        } else {
          console.error("Invalid toolgroups data format:", toolgroups);
        }
      } catch (error) {
        console.error("Error fetching toolgroups:", error);
        if (error instanceof Error) {
          console.error("Error details:", {
            name: error.name,
            message: error.message,
            stack: error.stack,
          });
        }
      }
    };

    fetchToolgroups();

    const fetchVectorDBs = async () => {
      try {
        const vectorDBs = await client.vectorDBs.list();

        const vectorDBsArray = Array.isArray(vectorDBs) ? vectorDBs : [];

        if (vectorDBsArray && Array.isArray(vectorDBsArray)) {
          setAvailableVectorDBs(vectorDBsArray);
        } else {
          console.error("Invalid vector DBs data format:", vectorDBs);
        }
      } catch (error) {
        console.error("Error fetching vector DBs:", error);
      }
    };

    fetchVectorDBs();
  }, [client, loadAgentSessions, loadAgentConfig]);

  const createNewAgent = useCallback(
    async (
      name: string,
      instructions: string,
      model: string,
      toolgroups: string[] = [],
      vectorDBs: string[] = []
    ) => {
      try {
        const processedToolgroups = toolgroups.map(toolgroup => {
          if (toolgroup === "builtin::rag" && vectorDBs.length > 0) {
            return {
              name: "builtin::rag/knowledge_search",
              args: {
                vector_db_ids: vectorDBs,
              },
            };
          }
          return toolgroup;
        });

        const agentConfig = {
          model,
          instructions,
          name: name || undefined,
          enable_session_persistence: true,
          toolgroups:
            processedToolgroups.length > 0 ? processedToolgroups : undefined,
        };

        const response = await client.agents.create({
          agent_config: agentConfig,
        });

        const agentList = await client.agents.list();
        setAgents(
          (agentList.data as Array<{
            agent_id: string;
            agent_config?: {
              agent_name?: string;
              name?: string;
              instructions?: string;
            };
            [key: string]: unknown;
          }>) || []
        );

        setSelectedAgentId(response.agent_id);
        await loadAgentConfig(response.agent_id);
        await loadAgentSessions(response.agent_id);

        return response.agent_id;
      } catch (error) {
        console.error("Error creating agent:", error);
        throw error;
      }
    },
    [client, loadAgentSessions, loadAgentConfig]
  );

  const handleVectorDBCreated = useCallback(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    async (_vectorDbId: string) => {
      setShowCreateVectorDB(false);

      try {
        const vectorDBs = await client.vectorDBs.list();
        const vectorDBsArray = Array.isArray(vectorDBs) ? vectorDBs : [];

        if (vectorDBsArray && Array.isArray(vectorDBsArray)) {
          setAvailableVectorDBs(vectorDBsArray);
        }
      } catch (error) {
        console.error("Error refreshing vector DBs:", error);
      }
    },
    [client]
  );

  const deleteAgent = useCallback(
    async (agentId: string) => {
      if (
        confirm(
          "Are you sure you want to delete this agent? This action cannot be undone and will delete the agent and all its sessions."
        )
      ) {
        try {
          // there's a known error where the delete API returns 500 even on success
          try {
            await client.agents.delete(agentId);
            console.log("Agent deleted successfully");
          } catch (deleteError) {
            // log the error but don't re-throw - we know deletion succeeded
            console.log(
              "Agent delete API returned error (but deletion likely succeeded):",
              deleteError
            );
          }

          SessionUtils.clearAgentCache(agentId);

          const agentList = await client.agents.list();
          setAgents(
            (agentList.data as Array<{
              agent_id: string;
              agent_config?: {
                agent_name?: string;
                name?: string;
                instructions?: string;
              };
              [key: string]: unknown;
            }>) || []
          );

          // if we delete current agent, switch to another
          if (selectedAgentId === agentId) {
            const remainingAgents = agentList.data?.filter(
              (a: { [key: string]: unknown }) =>
                (a as { agent_id: string }).agent_id !== agentId
            );
            if (remainingAgents && remainingAgents.length > 0) {
              const newAgent = remainingAgents[0] as {
                agent_id: string;
                agent_config?: {
                  agent_name?: string;
                  name?: string;
                  instructions?: string;
                };
                [key: string]: unknown;
              };
              setSelectedAgentId(newAgent.agent_id);
              SessionUtils.saveCurrentAgentId(newAgent.agent_id);
              await loadAgentConfig(newAgent.agent_id);
              await loadAgentSessions(newAgent.agent_id);
            } else {
              // no agents left
              setSelectedAgentId("");
              setCurrentSession(null);
              setSelectedAgentConfig(null);
            }
          }
        } catch (error) {
          console.error("Error deleting agent:", error);

          // check if this is known server bug where deletion succeeds but returns 500
          // The error message will typically contain status codes or "Could not find agent"
          const errorMessage =
            error instanceof Error ? error.message : String(error);
          const isKnownServerBug =
            errorMessage.includes("500") ||
            errorMessage.includes("Internal Server Error") ||
            errorMessage.includes("Could not find agent") ||
            errorMessage.includes("400");

          if (isKnownServerBug) {
            console.log(
              "Agent deletion succeeded despite error, cleaning up UI"
            );
            SessionUtils.clearAgentCache(agentId);
            try {
              const agentList = await client.agents.list();
              setAgents(
                (agentList.data as Array<{
                  agent_id: string;
                  agent_config?: {
                    agent_name?: string;
                    name?: string;
                    instructions?: string;
                  };
                  [key: string]: unknown;
                }>) || []
              );

              if (selectedAgentId === agentId) {
                const remainingAgents = agentList.data?.filter(
                  (a: { [key: string]: unknown }) =>
                    (a as { agent_id: string }).agent_id !== agentId
                );
                if (remainingAgents && remainingAgents.length > 0) {
                  const newAgent = remainingAgents[0] as {
                    agent_id: string;
                    agent_config?: {
                      agent_name?: string;
                      name?: string;
                      instructions?: string;
                    };
                    [key: string]: unknown;
                  };
                  setSelectedAgentId(newAgent.agent_id);
                  SessionUtils.saveCurrentAgentId(newAgent.agent_id);
                  await loadAgentConfig(newAgent.agent_id);
                  await loadAgentSessions(newAgent.agent_id);
                } else {
                  // no agents left
                  setSelectedAgentId("");
                  setCurrentSession(null);
                  setSelectedAgentConfig(null);
                }
              }
            } catch (refreshError) {
              console.error("Error refreshing agents list:", refreshError);
            }
          } else {
            // show error that we don't know about to user
            console.error("Unexpected error during agent deletion:", error);
            if (error instanceof Error) {
              alert(`Failed to delete agent: ${error.message}`);
            }
          }
        }
      }
    },
    [client, selectedAgentId, loadAgentConfig, loadAgentSessions]
  );

  const handleModelChange = useCallback((newModel: string) => {
    setSelectedModel(newModel);
    setCurrentSession(prev =>
      prev
        ? {
            ...prev,
            selectedModel: newModel,
            updatedAt: Date.now(),
          }
        : prev
    );
  }, []);

  useEffect(() => {
    if (currentSession) {
      SessionUtils.saveCurrentSessionId(
        currentSession.id,
        currentSession.agentId
      );
      // cache session data
      SessionUtils.saveSessionData(currentSession.agentId, currentSession);
      // only update selectedModel if the session has a valid model and it's different from current
      if (
        currentSession.selectedModel &&
        currentSession.selectedModel !== selectedModel
      ) {
        setSelectedModel(currentSession.selectedModel);
      }
    }
  }, [currentSession, selectedModel]);

  useEffect(() => {
    const fetchModels = async () => {
      try {
        setModelsLoading(true);
        setModelsError(null);
        const modelList = await client.models.list();

        // store all models (including embedding models for vector DB creation)
        setModels(modelList);

        // set default LLM model for chat
        const llmModels = modelList.filter(model => model.model_type === "llm");
        if (llmModels.length > 0) {
          handleModelChange(llmModels[0].identifier);
        }
      } catch (err) {
        console.error("Error fetching models:", err);
        setModelsError("Failed to fetch available models");
      } finally {
        setModelsLoading(false);
      }
    };

    fetchModels();
  }, [client, handleModelChange]);

  // load agent sessions after both agents and models are ready
  useEffect(() => {
    if (
      selectedAgentId &&
      !agentsLoading &&
      !modelsLoading &&
      selectedModel &&
      !currentSession
    ) {
      loadAgentSessions(selectedAgentId);
    }
  }, [
    selectedAgentId,
    agentsLoading,
    modelsLoading,
    selectedModel,
    currentSession,
    loadAgentSessions,
  ]);

  const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setInput(e.target.value);
  };

  const handleSubmit = async (event?: { preventDefault?: () => void }) => {
    event?.preventDefault?.();
    if (!input.trim()) return;

    const userMessage: Message = {
      id: Date.now().toString(),
      role: "user",
      content: input.trim(),
      createdAt: new Date(),
    };

    setCurrentSession(prev => {
      if (!prev) return prev;
      const updatedSession = {
        ...prev,
        messages: [...prev.messages, userMessage],
        updatedAt: Date.now(),
      };
      // update cache with new message
      SessionUtils.saveSessionData(prev.agentId, updatedSession);
      return updatedSession;
    });
    setInput("");

    await handleSubmitWithContent(userMessage.content);
  };

  const handleSubmitWithContent = async (content: string) => {
    if (!currentSession || !selectedAgentId) return;

    setIsGenerating(true);
    setError(null);

    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    const abortController = new AbortController();
    abortControllerRef.current = abortController;

    try {
      const userMessage = {
        role: "user" as const,
        content,
      };

      const turnParams: TurnCreateParams = {
        messages: [userMessage],
        stream: true,
      };

      const response = await client.agents.turn.create(
        selectedAgentId,
        currentSession.id,
        turnParams,
        {
          signal: abortController.signal,
          timeout: 300000, // 5 minutes timeout for RAG queries
        } as { signal: AbortSignal; timeout: number }
      );

      const assistantMessage: Message = {
        id: (Date.now() + 1).toString(),
        role: "assistant",
        content: "",
        createdAt: new Date(),
      };

      const processChunk = (
        chunk: unknown
      ): { text: string | null; isToolCall: boolean } => {
        const chunkObj = chunk as Record<string, unknown>;

        // Skip turn_complete events to avoid duplicate content
        // These events contain the full accumulated content which we already have from streaming deltas
        if (
          chunkObj?.event &&
          typeof chunkObj.event === "object" &&
          chunkObj.event !== null
        ) {
          const event = chunkObj.event as Record<string, unknown>;
          if (
            event?.payload &&
            typeof event.payload === "object" &&
            event.payload !== null
          ) {
            const payload = event.payload as Record<string, unknown>;
            if (payload.event_type === "turn_complete") {
              return { text: null, isToolCall: false };
            }
          }
        }

        // helper to check if content contains function call JSON
        const containsToolCall = (content: string): boolean => {
          return (
            content.includes('"type": "function"') ||
            content.includes('"name": "knowledge_search"') ||
            content.includes('"parameters":') ||
            !!content.match(/\{"type":\s*"function".*?\}/)
          );
        };

        let isToolCall = false;
        let potentialContent = "";

        if (typeof chunk === "string") {
          potentialContent = chunk;
          isToolCall = containsToolCall(chunk);
        }

        if (
          chunkObj?.delta &&
          typeof chunkObj.delta === "object" &&
          chunkObj.delta !== null
        ) {
          const delta = chunkObj.delta as Record<string, unknown>;
          if ("tool_calls" in delta) {
            isToolCall = true;
          }
          if (typeof delta.text === "string") {
            potentialContent = delta.text;
            if (containsToolCall(delta.text)) {
              isToolCall = true;
            }
          }
        }

        if (
          chunkObj?.event &&
          typeof chunkObj.event === "object" &&
          chunkObj.event !== null
        ) {
          const event = chunkObj.event as Record<string, unknown>;

          if (
            event?.payload &&
            typeof event.payload === "object" &&
            event.payload !== null
          ) {
            const payload = event.payload as Record<string, unknown>;
            if (typeof payload.content === "string") {
              potentialContent = payload.content;
              if (containsToolCall(payload.content)) {
                isToolCall = true;
              }
            }

            if (
              payload?.delta &&
              typeof payload.delta === "object" &&
              payload.delta !== null
            ) {
              const delta = payload.delta as Record<string, unknown>;
              if (typeof delta.text === "string") {
                potentialContent = delta.text;
                if (containsToolCall(delta.text)) {
                  isToolCall = true;
                }
              }
            }
          }

          if (
            event?.delta &&
            typeof event.delta === "object" &&
            event.delta !== null
          ) {
            const delta = event.delta as Record<string, unknown>;
            if (typeof delta.text === "string") {
              potentialContent = delta.text;
              if (containsToolCall(delta.text)) {
                isToolCall = true;
              }
            }
            if (typeof delta.content === "string") {
              // eslint-disable-next-line @typescript-eslint/no-unused-vars
              potentialContent = delta.content;
              if (containsToolCall(delta.content)) {
                isToolCall = true;
              }
            }
          }
        }

        // if it's a tool call, skip it (don't display in chat)
        if (isToolCall) {
          return { text: null, isToolCall: true };
        }

        let text: string | null = null;

        if (
          chunkObj?.delta &&
          typeof chunkObj.delta === "object" &&
          chunkObj.delta !== null
        ) {
          const delta = chunkObj.delta as Record<string, unknown>;
          if (typeof delta.text === "string") {
            text = extractCleanText(delta.text);
          }
        }

        if (
          !text &&
          chunkObj?.event &&
          typeof chunkObj.event === "object" &&
          chunkObj.event !== null
        ) {
          const event = chunkObj.event as Record<string, unknown>;

          if (
            event?.payload &&
            typeof event.payload === "object" &&
            event.payload !== null
          ) {
            const payload = event.payload as Record<string, unknown>;

            if (typeof payload.content === "string") {
              text = extractCleanText(payload.content);
            }

            if (
              !text &&
              payload?.turn &&
              typeof payload.turn === "object" &&
              payload.turn !== null
            ) {
              const turn = payload.turn as Record<string, unknown>;
              if (
                turn?.output_message &&
                typeof turn.output_message === "object" &&
                turn.output_message !== null
              ) {
                const outputMessage = turn.output_message as Record<
                  string,
                  unknown
                >;
                if (typeof outputMessage.content === "string") {
                  text = extractCleanText(outputMessage.content);
                }
              }

              if (
                !text &&
                turn?.steps &&
                Array.isArray(turn.steps) &&
                turn.steps.length > 0
              ) {
                for (const step of turn.steps) {
                  if (step && typeof step === "object" && step !== null) {
                    const stepObj = step as Record<string, unknown>;
                    if (
                      stepObj?.model_response &&
                      typeof stepObj.model_response === "object" &&
                      stepObj.model_response !== null
                    ) {
                      const modelResponse = stepObj.model_response as Record<
                        string,
                        unknown
                      >;
                      if (typeof modelResponse.content === "string") {
                        text = extractCleanText(modelResponse.content);
                        break;
                      }
                    }
                  }
                }
              }
            }

            if (
              !text &&
              payload?.delta &&
              typeof payload.delta === "object" &&
              payload.delta !== null
            ) {
              const delta = payload.delta as Record<string, unknown>;
              if (typeof delta.text === "string") {
                text = extractCleanText(delta.text);
              }
            }
          }

          if (
            !text &&
            event?.delta &&
            typeof event.delta === "object" &&
            event.delta !== null
          ) {
            const delta = event.delta as Record<string, unknown>;
            if (typeof delta.text === "string") {
              text = extractCleanText(delta.text);
            }
            if (!text && typeof delta.content === "string") {
              text = extractCleanText(delta.content);
            }
          }
        }

        if (
          !text &&
          chunkObj?.choices &&
          Array.isArray(chunkObj.choices) &&
          chunkObj.choices.length > 0
        ) {
          const choice = chunkObj.choices[0] as Record<string, unknown>;
          if (
            choice?.delta &&
            typeof choice.delta === "object" &&
            choice.delta !== null
          ) {
            const delta = choice.delta as Record<string, unknown>;
            if (typeof delta.content === "string") {
              text = extractCleanText(delta.content);
            }
          }
        }

        if (!text && typeof chunk === "string") {
          text = extractCleanText(chunk);
        }

        return { text, isToolCall: false };
      };
      setCurrentSession(prev => {
        if (!prev) return null;
        const updatedSession = {
          ...prev,
          messages: [...prev.messages, assistantMessage],
          updatedAt: Date.now(),
        };
        // update cache with assistant message
        SessionUtils.saveSessionData(prev.agentId, updatedSession);
        return updatedSession;
      });

      let fullContent = "";

      for await (const chunk of response) {
        const { text: deltaText } = processChunk(chunk);

        // logging for debugging function calls
        // if (deltaText && deltaText.includes("knowledge_search")) {
        //   console.log("🔍 Function call detected in text output:", deltaText);
        //   console.log("🔍 Original chunk:", JSON.stringify(chunk, null, 2));
        // }

        if (chunk && typeof chunk === "object" && "event" in chunk) {
          const event = (
            chunk as {
              event: {
                payload?: {
                  event_type?: string;
                  turn?: { output_message?: { content?: string } };
                };
              };
            }
          ).event;
          if (event?.payload?.event_type === "turn_complete") {
            const content = event?.payload?.turn?.output_message?.content;
            if (content && content.includes("knowledge_search")) {
              console.log("🔍 Function call found in turn_complete:", content);
            }
          }
        }

        if (deltaText) {
          fullContent += deltaText;

          flushSync(() => {
            setCurrentSession(prev => {
              if (!prev) return null;
              const newMessages = [...prev.messages];
              const last = newMessages[newMessages.length - 1];
              if (last.role === "assistant") {
                last.content = fullContent;
              }
              const updatedSession = {
                ...prev,
                messages: newMessages,
                updatedAt: Date.now(),
              };
              // update cache with streaming content
              if (fullContent.length % 100 === 0) {
                // Only cache every 100 characters
                SessionUtils.saveSessionData(prev.agentId, updatedSession);
              }
              return updatedSession;
            });
          });
        }
      }
    } catch (err) {
      if (err instanceof Error && err.name === "AbortError") {
        console.log("Request aborted");
        return;
      }

      console.error("Error sending message:", err);
      setError("Failed to send message. Please try again.");
      setCurrentSession(prev =>
        prev
          ? {
              ...prev,
              messages: prev.messages.slice(0, -1),
              updatedAt: Date.now(),
            }
          : prev
      );
    } finally {
      setIsGenerating(false);
      abortControllerRef.current = null;
      // cache final session state after streaming completes
      setCurrentSession(prev => {
        if (prev) {
          SessionUtils.saveSessionData(prev.agentId, prev);
        }
        return prev;
      });
    }
  };
  const suggestions = [
    "Write a Python function that prints 'Hello, World!'",
    "Explain step-by-step how to solve this math problem: If x² + 6x + 9 = 25, what is x?",
    "Design a simple algorithm to find the longest palindrome in a string.",
  ];

  const append = (message: { role: "user"; content: string }) => {
    const newMessage: Message = {
      id: Date.now().toString(),
      role: message.role,
      content: message.content,
      createdAt: new Date(),
    };
    setCurrentSession(prev =>
      prev
        ? {
            ...prev,
            messages: [...prev.messages, newMessage],
            updatedAt: Date.now(),
          }
        : prev
    );
    handleSubmitWithContent(newMessage.content);
  };

  const clearChat = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
      setIsGenerating(false);
    }

    setCurrentSession(prev =>
      prev ? { ...prev, messages: [], updatedAt: Date.now() } : prev
    );
    setError(null);
  };

  const handleRAGFileUpload = async (file: File) => {
    if (!selectedAgentConfig?.toolgroups || !selectedAgentId) {
      setError("No agent selected or agent has no RAG tools configured");
      return;
    }

    // find RAG toolgroups that have vector_db_ids configured
    const ragToolgroups = selectedAgentConfig.toolgroups.filter(toolgroup => {
      if (typeof toolgroup === "object" && toolgroup.name?.includes("rag")) {
        return toolgroup.args && "vector_db_ids" in toolgroup.args;
      }
      return false;
    });

    if (ragToolgroups.length === 0) {
      setError("Current agent has no vector databases configured for RAG");
      return;
    }

    try {
      setError(null);
      console.log("Uploading file using RAG tool...");

      setUploadNotification({
        show: true,
        message: `📄 Uploading and indexing "${file.name}"...`,
        type: "loading",
      });

      const vectorDbIds = ragToolgroups.flatMap(toolgroup => {
        if (
          typeof toolgroup === "object" &&
          toolgroup.args &&
          "vector_db_ids" in toolgroup.args
        ) {
          return toolgroup.args.vector_db_ids as string[];
        }
        return [];
      });

      // determine mime type from file extension - this should be in the Llama Stack Client IMO
      const getContentType = (filename: string): string => {
        const ext = filename.toLowerCase().split(".").pop();
        switch (ext) {
          case "pdf":
            return "application/pdf";
          case "txt":
            return "text/plain";
          case "md":
            return "text/markdown";
          case "html":
            return "text/html";
          case "csv":
            return "text/csv";
          case "json":
            return "application/json";
          case "docx":
            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
          case "doc":
            return "application/msword";
          default:
            return "application/octet-stream";
        }
      };

      const mimeType = getContentType(file.name);
      let fileContent: string;

      // handle text files vs binary files differently
      const isTextFile =
        mimeType.startsWith("text/") ||
        mimeType === "application/json" ||
        mimeType === "text/markdown" ||
        mimeType === "text/html" ||
        mimeType === "text/csv";

      if (isTextFile) {
        fileContent = await file.text();
      } else {
        // for PDFs and other binary files, create a data URL
        // use FileReader for efficient base64 conversion
        fileContent = await new Promise<string>((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = () => resolve(reader.result as string);
          reader.onerror = () => reject(reader.error);
          reader.readAsDataURL(file);
        });
      }

      for (const vectorDbId of vectorDbIds) {
        await client.toolRuntime.ragTool.insert({
          documents: [
            {
              content: fileContent,
              document_id: `${file.name}-${Date.now()}`,
              metadata: {
                filename: file.name,
                file_size: file.size,
                uploaded_at: new Date().toISOString(),
                agent_id: selectedAgentId,
              },
              mime_type: mimeType,
            },
          ],
          vector_db_id: vectorDbId,
          // TODO: parameterize this somewhere, probably in settings
          chunk_size_in_tokens: 512,
        });
      }

      console.log("✅ File successfully uploaded using RAG tool");

      setUploadNotification({
        show: true,
        message: `📄 File "${file.name}" uploaded and indexed successfully!`,
        type: "success",
      });

      setTimeout(() => {
        setUploadNotification(prev => ({ ...prev, show: false }));
      }, 4000);
    } catch (err) {
      console.error("Error uploading file using RAG tool:", err);
      const errorMessage =
        err instanceof Error
          ? `Failed to upload file: ${err.message}`
          : "Failed to upload file using RAG tool";

      setUploadNotification({
        show: true,
        message: errorMessage,
        type: "error",
      });

      setTimeout(() => {
        setUploadNotification(prev => ({ ...prev, show: false }));
      }, 6000);
    }
  };

  return (
    <div className="flex flex-col h-full w-full max-w-7xl mx-auto">
      {/* Upload Notification */}
      {uploadNotification.show && (
        <div
          className={`fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg transition-all duration-300 ${
            uploadNotification.type === "success"
              ? "bg-green-100 border border-green-300 text-green-800"
              : uploadNotification.type === "error"
                ? "bg-red-100 border border-red-300 text-red-800"
                : "bg-blue-100 border border-blue-300 text-blue-800"
          }`}
        >
          <div className="flex items-center gap-2">
            {uploadNotification.type === "loading" && (
              <div className="animate-spin rounded-full h-4 w-4 border-2 border-blue-600 border-t-transparent"></div>
            )}
            <span className="text-sm font-medium">
              {uploadNotification.message}
            </span>
            {uploadNotification.type !== "loading" && (
              <button
                onClick={() =>
                  setUploadNotification(prev => ({ ...prev, show: false }))
                }
                className="ml-2 text-gray-400 hover:text-gray-600"
              >
                ✕
              </button>
            )}
          </div>
        </div>
      )}

      {/* Header */}
      <div className="mb-6">
        <div className="flex justify-between items-center mb-4">
          <h1 className="text-3xl font-bold">Agent Session</h1>
          <div className="flex items-center gap-3">
            {!agentsLoading && agents.length > 0 && (
              <div className="flex items-center gap-2">
                <label className="text-sm font-medium">Agent Session:</label>
                <Select
                  value={selectedAgentId}
                  onValueChange={agentId => {
                    setSelectedAgentId(agentId);
                    SessionUtils.saveCurrentAgentId(agentId);
                    loadAgentConfig(agentId);
                    loadAgentSessions(agentId);
                  }}
                  disabled={agentsLoading}
                >
                  <SelectTrigger className="w-[200px]">
                    <SelectValue
                      placeholder={
                        agentsLoading ? "Loading..." : "Select Agent Session"
                      }
                    />
                  </SelectTrigger>
                  <SelectContent>
                    {agents.map(agent => (
                      <SelectItem key={agent.agent_id} value={agent.agent_id}>
                        {(() => {
                          if (
                            agent.agent_config &&
                            "name" in agent.agent_config &&
                            typeof agent.agent_config.name === "string"
                          ) {
                            return agent.agent_config.name;
                          }
                          if (
                            agent.agent_config &&
                            "agent_name" in agent.agent_config &&
                            typeof agent.agent_config.agent_name === "string"
                          ) {
                            return agent.agent_config.agent_name;
                          }
                          return `Agent ${agent.agent_id.slice(0, 8)}...`;
                        })()}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {selectedAgentId && (
                  <Button
                    onClick={() => deleteAgent(selectedAgentId)}
                    variant="outline"
                    size="sm"
                    className="text-destructive hover:text-destructive hover:bg-destructive/10"
                    title="Delete current agent"
                  >
                    <Trash2 className="h-3 w-3" />
                  </Button>
                )}
              </div>
            )}
            <Button
              onClick={() => setShowCreateAgent(true)}
              variant="outline"
              size="sm"
            >
              + New Agent
            </Button>
            {!agentsLoading && agents.length > 0 && (
              <Button
                variant="outline"
                onClick={clearChat}
                disabled={isGenerating}
              >
                Clear Chat
              </Button>
            )}
          </div>
        </div>
      </div>
      {/* Main Two-Column Layout */}
      <div className="flex flex-1 gap-6 min-h-0 flex-col lg:flex-row">
        {/* Left Column - Configuration Panel */}
        <div className="w-full lg:w-80 lg:flex-shrink-0 space-y-6 p-4 border border-border rounded-lg bg-muted/30">
          <h2 className="text-lg font-semibold border-b pb-2 text-left">
            Settings
          </h2>

          {/* Model Configuration */}
          <div className="space-y-4 text-left">
            <h3 className="text-lg font-semibold border-b pb-2 text-left">
              Model Configuration
            </h3>
            <div className="space-y-3">
              <div>
                <label className="text-sm font-medium block mb-2">Model</label>
                <Select
                  value={selectedModel}
                  onValueChange={handleModelChange}
                  disabled={isModelsLoading || isGenerating}
                >
                  <SelectTrigger className="w-full">
                    <SelectValue
                      placeholder={
                        isModelsLoading ? "Loading..." : "Select Model"
                      }
                    />
                  </SelectTrigger>
                  <SelectContent>
                    {models
                      .filter(model => model.model_type === "llm")
                      .map(model => (
                        <SelectItem
                          key={model.identifier}
                          value={model.identifier}
                        >
                          {model.identifier}
                        </SelectItem>
                      ))}
                  </SelectContent>
                </Select>
                {modelsError && (
                  <p className="text-destructive text-xs mt-1">{modelsError}</p>
                )}
              </div>

              <div>
                <label className="text-sm font-medium block mb-2">
                  Agent Instructions
                </label>
                <div className="w-full h-24 px-3 py-2 text-sm border border-input rounded-md bg-muted text-muted-foreground overflow-y-auto">
                  {(selectedAgentId &&
                    agents.find(a => a.agent_id === selectedAgentId)
                      ?.agent_config?.instructions) ||
                    "No agent selected"}
                </div>
                <p className="text-xs text-muted-foreground mt-1">
                  Instructions are set when creating an agent and cannot be
                  changed.
                </p>
              </div>
            </div>
          </div>

          {/* Agent Tools */}
          <div className="space-y-4 text-left">
            <h3 className="text-lg font-semibold border-b pb-2 text-left">
              Agent Tools
            </h3>
            <div className="space-y-3">
              <div>
                <label className="text-sm font-medium block mb-2 text-muted-foreground">
                  Configured Tools (Coming Soon)
                </label>
                <div className="space-y-2">
                  {selectedAgentConfig?.toolgroups &&
                  selectedAgentConfig.toolgroups.length > 0 ? (
                    selectedAgentConfig.toolgroups.map(
                      (
                        toolgroup:
                          | string
                          | { name: string; args: Record<string, unknown> },
                        index: number
                      ) => {
                        const toolName =
                          typeof toolgroup === "string"
                            ? toolgroup
                            : toolgroup.name;
                        const toolArgs =
                          typeof toolgroup === "object" ? toolgroup.args : null;

                        const isRAGTool = toolName.includes("rag");
                        const displayName = isRAGTool ? "RAG Search" : toolName;
                        const displayIcon = isRAGTool
                          ? "🔍"
                          : toolName.includes("search")
                            ? "🌐"
                            : "🔧";

                        return (
                          <div
                            key={index}
                            className="p-3 border border-input rounded-md bg-muted text-muted-foreground"
                          >
                            <div className="flex items-center justify-between">
                              <div className="flex items-center gap-2">
                                <span className="text-sm">{displayIcon}</span>
                                <span className="text-sm font-medium text-primary">
                                  {displayName}
                                </span>
                              </div>
                            </div>
                            {isRAGTool && toolArgs && toolArgs.vector_db_ids ? (
                              <div className="mt-2 text-xs text-muted-foreground">
                                <span className="font-medium">
                                  Vector Databases:
                                </span>
                                <div className="mt-1 flex flex-wrap gap-1">
                                  {Array.isArray(toolArgs.vector_db_ids) ? (
                                    toolArgs.vector_db_ids.map(
                                      (dbId: string, idx: number) => (
                                        <code
                                          key={idx}
                                          className="px-1.5 py-0.5 bg-muted-foreground/10 rounded text-xs"
                                        >
                                          {dbId}
                                        </code>
                                      )
                                    )
                                  ) : (
                                    <code className="px-1.5 py-0.5 bg-muted-foreground/10 rounded text-xs">
                                      {String(toolArgs.vector_db_ids)}
                                    </code>
                                  )}
                                </div>
                              </div>
                            ) : null}
                            {!isRAGTool &&
                              toolArgs &&
                              Object.keys(toolArgs).length > 0 && (
                                <div className="mt-2 text-xs text-muted-foreground">
                                  <span className="font-medium">
                                    Configuration:
                                  </span>{" "}
                                  {Object.keys(toolArgs).length} parameter
                                  {Object.keys(toolArgs).length > 1 ? "s" : ""}
                                </div>
                              )}
                          </div>
                        );
                      }
                    )
                  ) : (
                    <div className="p-3 border border-input rounded-md bg-muted text-center">
                      <p className="text-sm text-muted-foreground">
                        No tools configured
                      </p>
                      <p className="text-xs text-muted-foreground mt-1">
                        This agent only has text generation capabilities
                      </p>
                    </div>
                  )}
                </div>
                <p className="text-xs text-muted-foreground mt-2">
                  Tools are configured when creating an agent and provide
                  additional capabilities like web search, math calculations, or
                  RAG document retrieval.
                </p>
              </div>
            </div>
          </div>
        </div>

        {/* Right Column - Chat Interface */}
        <div className="flex-1 flex flex-col min-h-0 p-4 border border-border rounded-lg bg-background">
          {error && (
            <div className="mb-4 p-3 bg-destructive/10 border border-destructive/20 rounded-md">
              <p className="text-destructive text-sm">{error}</p>
            </div>
          )}

          {!agentsLoading && agents.length === 0 ? (
            <div className="flex-1 flex items-center justify-center">
              <div className="text-center space-y-4 max-w-md">
                <div className="text-6xl mb-4">🦙</div>
                <h2 className="text-2xl font-semibold text-muted-foreground">
                  Create an Agent with Llama Stack
                </h2>
                <p className="text-muted-foreground">
                  To get started, create your first agent. Each agent is
                  configured with specific instructions, models, and tools to
                  help you with different tasks.
                </p>
                <Button
                  onClick={() => setShowCreateAgent(true)}
                  size="lg"
                  className="mt-4"
                >
                  Create Your First Agent
                </Button>
              </div>
            </div>
          ) : (
            <Chat
              className="flex-1"
              messages={currentSession?.messages || []}
              handleSubmit={handleSubmit}
              input={input}
              handleInputChange={handleInputChange}
              isGenerating={isGenerating}
              append={append}
              suggestions={suggestions}
              setMessages={messages =>
                setCurrentSession(prev =>
                  prev ? { ...prev, messages, updatedAt: Date.now() } : prev
                )
              }
              onRAGFileUpload={handleRAGFileUpload}
            />
          )}
        </div>
      </div>

      {/* Create Agent Modal */}
      {showCreateAgent && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <Card className="w-[500px] p-6 space-y-4">
            <h3 className="text-lg font-semibold">Create New Agent</h3>

            <div className="space-y-4">
              <div>
                <label className="text-sm font-medium block mb-2">
                  Agent Name (optional)
                </label>
                <Input
                  value={newAgentName}
                  onChange={e => setNewAgentName(e.target.value)}
                  placeholder="My Custom Agent"
                />
              </div>

              <div>
                <label className="text-sm font-medium block mb-2">Model</label>
                <Select value={selectedModel} onValueChange={setSelectedModel}>
                  <SelectTrigger>
                    <SelectValue placeholder="Select Model" />
                  </SelectTrigger>
                  <SelectContent>
                    {models
                      .filter(model => model.model_type === "llm")
                      .map(model => (
                        <SelectItem
                          key={model.identifier}
                          value={model.identifier}
                        >
                          {model.identifier}
                        </SelectItem>
                      ))}
                  </SelectContent>
                </Select>
              </div>

              <div>
                <label className="text-sm font-medium block mb-2">
                  System Instructions
                </label>
                <textarea
                  value={newAgentInstructions}
                  onChange={e => setNewAgentInstructions(e.target.value)}
                  placeholder="You are a helpful assistant."
                  className="w-full h-32 px-3 py-2 text-sm border border-input rounded-md resize-none focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
                />
              </div>

              <div>
                <label className="text-sm font-medium block mb-2">
                  Tools (optional)
                </label>
                <label className="text-sm font-small block mb-2">
                  NOTE: Tools are not yet implemented
                </label>
                <p className="text-xs text-muted-foreground mb-2">
                  Available toolgroups: {availableToolgroups.length} found
                </p>
                <div className="space-y-2">
                  {availableToolgroups.length === 0 ? (
                    <p className="text-sm text-muted-foreground">
                      Loading toolgroups...
                    </p>
                  ) : (
                    availableToolgroups.map(toolgroup => (
                      <label
                        key={toolgroup.identifier}
                        className="flex items-center space-x-2"
                      >
                        <input
                          type="checkbox"
                          checked={selectedToolgroups.includes(
                            toolgroup.identifier
                          )}
                          onChange={e => {
                            if (e.target.checked) {
                              setSelectedToolgroups(prev => {
                                const newSelection = [
                                  ...prev,
                                  toolgroup.identifier,
                                ];
                                return newSelection;
                              });
                            } else {
                              setSelectedToolgroups(prev => {
                                const newSelection = prev.filter(
                                  id => id !== toolgroup.identifier
                                );
                                return newSelection;
                              });
                            }
                          }}
                          className="rounded border-input"
                        />
                        <span className="text-sm">
                          <code className="bg-muted px-1 rounded text-xs">
                            {toolgroup.identifier}
                          </code>
                          <span className="text-muted-foreground ml-2">
                            ({toolgroup.provider_id})
                          </span>
                        </span>
                      </label>
                    ))
                  )}
                </div>
                {selectedToolgroups.length === 0 && (
                  <p className="text-xs text-muted-foreground mt-1">
                    No tools selected - agent will only have text generation
                    capabilities.
                  </p>
                )}
                <p className="text-xs text-muted-foreground mt-2 p-2 bg-muted/50 border border-border rounded">
                  <strong>Note:</strong> Selected tools will be configured for
                  the agent. Some tools like RAG may require additional vector
                  DB configuration, and web search tools need API keys. Basic
                  text generation agents work without tools.
                </p>
              </div>

              {/* Vector DB Configuration for RAG */}
              {selectedToolgroups.includes("builtin::rag") && (
                <div>
                  <label className="text-sm font-medium block mb-2">
                    Vector Databases for RAG
                  </label>
                  <div className="flex items-center gap-2 mb-2">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={() => setShowCreateVectorDB(true)}
                    >
                      + Create Vector DB
                    </Button>
                    <span className="text-xs text-muted-foreground">
                      {availableVectorDBs.length} available
                    </span>
                  </div>
                  <div className="space-y-2 max-h-32 overflow-y-auto">
                    {availableVectorDBs.length === 0 ? (
                      <p className="text-sm text-muted-foreground">
                        No vector databases available. Create one to use RAG
                        tools.
                      </p>
                    ) : (
                      availableVectorDBs.map(vectorDB => (
                        <label
                          key={vectorDB.identifier}
                          className="flex items-center space-x-2"
                        >
                          <input
                            type="checkbox"
                            checked={selectedVectorDBs.includes(
                              vectorDB.identifier
                            )}
                            onChange={e => {
                              if (e.target.checked) {
                                setSelectedVectorDBs(prev => [
                                  ...prev,
                                  vectorDB.identifier,
                                ]);
                              } else {
                                setSelectedVectorDBs(prev =>
                                  prev.filter(id => id !== vectorDB.identifier)
                                );
                              }
                            }}
                            className="rounded border-input"
                          />
                          <span className="text-sm">
                            <code className="bg-muted px-1 rounded text-xs">
                              {vectorDB.identifier}
                            </code>
                            {vectorDB.vector_db_name && (
                              <span className="text-muted-foreground ml-2">
                                ({vectorDB.vector_db_name})
                              </span>
                            )}
                          </span>
                        </label>
                      ))
                    )}
                  </div>
                  {selectedVectorDBs.length === 0 &&
                    selectedToolgroups.includes("builtin::rag") && (
                      <p className="text-xs text-muted-foreground mt-1">
                        ⚠️ RAG tool selected but no vector databases chosen.
                        Create or select a vector database.
                      </p>
                    )}
                </div>
              )}
            </div>

            <div className="flex gap-2 pt-4">
              <Button
                onClick={async () => {
                  try {
                    await createNewAgent(
                      newAgentName,
                      newAgentInstructions,
                      selectedModel,
                      selectedToolgroups,
                      selectedVectorDBs
                    );
                    setShowCreateAgent(false);
                    setNewAgentName("");
                    setNewAgentInstructions("You are a helpful assistant.");
                    setSelectedToolgroups([]);
                    setSelectedVectorDBs([]);
                  } catch (error) {
                    console.error("Failed to create agent:", error);
                  }
                }}
                className="flex-1"
                disabled={!selectedModel || !newAgentInstructions.trim()}
              >
                Create Agent
              </Button>
              <Button
                variant="outline"
                onClick={() => {
                  setShowCreateAgent(false);
                  setNewAgentName("");
                  setNewAgentInstructions("You are a helpful assistant.");
                  setSelectedToolgroups([]);
                  setSelectedVectorDBs([]);
                }}
                className="flex-1"
              >
                Cancel
              </Button>
            </div>
          </Card>
        </div>
      )}

      {/* Create Vector DB Modal */}
      {showCreateVectorDB && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <VectorDBCreator
            models={models}
            onVectorDBCreated={handleVectorDBCreated}
            onCancel={() => setShowCreateVectorDB(false)}
          />
        </div>
      )}
    </div>
  );
}
