import { ActionIcon, Alert, Badge, Box, Button, Code, Divider, Group, List, Loader, Modal, NumberInput, Paper, ScrollArea, Select, SimpleGrid, Stack, Switch, Text, Textarea, TextInput, Title, Tooltip } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import { IconArrowLeft, IconEye, IconInfoCircle, IconPlus, IconPlayerPlay, IconRobot, IconSend, IconStar, IconTrash } from "@tabler/icons-react";
import { useForm } from "@mantine/form";
import { useNavigate } from "react-router";
import { useRef, useState } from "react";
import ConfirmModal from "@/layouts/shared/ConfirmModal";

import type { AgentFormValues, PromptOption } from "./agent.types";
import { agentInitialValues, agentValidate, getPrecision } from "./agent.form";
import { REQUIRED_TUNING_KEYS, TUNING_CONFIG, type RequiredTuningKey } from "@/lib/features/chatbot/constants/constants";
import { makeAgentGlobal, testAgent, toggleAgentActive } from "@/lib/features/chatbot/agent/action";
import { createPrompt, deletePrompt } from "@/lib/features/chatbot/prompt/action";
import FileUploadField from "./FileUploadField";

// ── Quick guide modal ─────────────────────────────────────────────────────────

export function AgentQuickGuideModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
  return (
    <Modal opened={opened} onClose={onClose} title="Agent Quick Guide" size="xl" scrollAreaComponent={ScrollArea.Autosize}>
      <Stack gap="sm">
        <Alert color="blue" variant="light" title="What is an Agent?">
          An agent combines a prompt, AI models, a category key, and a data source URL. The Global Agent routes every query to the best child agent using semantic scoring (embedding + token overlap). Score threshold is 6/100 — below that, the Global Agent answers directly.
        </Alert>

        <Text fw={600} size="sm">
          📌 Category Key
        </Text>
        <Text size="sm" c="dimmed">
          Use lowercase, no spaces (e.g. <Code>accommodation</Code>, <Code>maps</Code>, <Code>bottles</Code>, <Code>dining</Code>).
        </Text>
        <List size="sm" spacing={2}>
          <List.Item>
            <Badge color="blue" size="xs">
              accommodation
            </Badge>{" "}
            — rooms, villas, resort bookings
          </List.Item>
          <List.Item>
            <Badge color="orange" size="xs">
              maps
            </Badge>{" "}
            — directions, resort location maps (special CSV format required)
          </List.Item>
          <List.Item>
            <Badge color="grape" size="xs">
              bottles / dining / concierge
            </Badge>{" "}
            — custom domains, any CSV structure
          </List.Item>
        </List>
        <Text size="xs" c="dimmed">
          Any custom key is supported. The richer the prompt text, the better the semantic match.
        </Text>

        <Divider />

        <Text fw={600} size="sm">
          📝 Required prompt placeholders
        </Text>
        <Text size="sm" c="dimmed">
          Every prompt <strong>must</strong> include all five placeholders — they are filled in automatically at runtime:
        </Text>
        <Box p="xs" style={{ background: "var(--mantine-color-gray-0)", borderRadius: 6 }}>
          {[
            ["{context}", "Retrieved data chunks relevant to the user query"],
            ["{user_query}", "The user's actual message"],
            ["{user_name}", "User's name or 'Traveler' as default"],
            ["{greeted}", "Whether the user has been greeted (true/false)"],
            ["{links_from_excel}", "Source URLs from the retrieved CSV rows"],
          ].map(([ph, desc]) => (
            <Group key={ph} gap="xs" wrap="nowrap" mb={2}>
              <Code style={{ minWidth: 175, fontSize: 11 }}>{ph}</Code>
              <Text size="xs" c="dimmed">
                {desc}
              </Text>
            </Group>
          ))}
        </Box>
        <Text size="xs" c="orange">
          Missing any placeholder → formatting error on every request.
        </Text>

        <Divider />

        <Text fw={600} size="sm">
          📊 Data Source URL
        </Text>
        <Text size="sm" c="dimmed">
          Paste a public CSV or Excel URL. Leave blank to use the server-level general dataset.
        </Text>
        <List size="sm" spacing={2}>
          <List.Item>Any column structure works — the first column becomes the row label.</List.Item>
          <List.Item>
            Column names contribute to routing score — use descriptive names (e.g.{" "}
            <Text component="code" size="xs">
              wine_name
            </Text>
            ,{" "}
            <Text component="code" size="xs">
              tasting_notes
            </Text>
            ).
          </List.Item>
          <List.Item>
            <strong>Maps agents only:</strong> CSV must have{" "}
            <Text component="code" size="xs">
              Resort_Name
            </Text>{" "}
            and{" "}
            <Text component="code" size="xs">
              Source_Link
            </Text>{" "}
            columns.
          </List.Item>
        </List>

        <Divider />

        <Text fw={600} size="sm">
          🔴 Active toggle
        </Text>
        <Text size="sm" c="dimmed">
          Inactive agents are never auto-selected in production. They still work in the Test panel.
        </Text>

        <Text fw={600} size="sm">
          🧪 Test button
        </Text>
        <Text size="sm" c="dimmed">
          Use <strong>Test Agent</strong> on the list or edit page to verify the agent responds correctly before activating.
        </Text>

        <Text fw={600} size="sm">
          🔍 Debugging
        </Text>
        <Text size="sm" c="dimmed">
          Check the Python server logs — every request logs the selected agent name, score, prompt excerpt, and data service used.
        </Text>
      </Stack>
    </Modal>
  );
}

// ── Test Agent Modal ──────────────────────────────────────────────────────────

type ChatMessage = { role: "user" | "bot"; text: string };
type ActiveMeta = {
  active_agent_id?: string;
  active_agent_name?: string;
  active_agent_source?: string;
  selected_agent_category_key?: string;
};

export function TestAgentModal({ opened, onClose, agentId, agentName }: { opened: boolean; onClose: () => void; agentId?: string; agentName?: string }) {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [input, setInput] = useState("");
  const [loading, setLoading] = useState(false);
  const [activeMeta, setActiveMeta] = useState<ActiveMeta | null>(null);
  const scrollRef = useRef<HTMLDivElement>(null);

  const send = async () => {
    const msg = input.trim();
    if (!msg || loading) return;
    setInput("");
    setMessages((prev) => [...prev, { role: "user", text: msg }]);
    setLoading(true);
    try {
      const res = await testAgent({ message: msg, agent_id: agentId });
      const data = res?.data ?? res;
      // Extract plain text from response
      const reply = data?.reply ?? data;
      const text = (typeof reply === "string" ? reply : null) || reply?.text || reply?.html?.replace(/<[^>]+>/g, " ") || JSON.stringify(reply);
      const responseMeta = data?.meta ?? {};
      const meta: ActiveMeta = {
        active_agent_id: responseMeta.active_agent_id ?? data?.active_agent_id,
        active_agent_name: responseMeta.active_agent_name ?? data?.active_agent_name,
        active_agent_source: responseMeta.active_agent_source ?? data?.active_agent_source,
        selected_agent_category_key: responseMeta.selected_agent_category_key ?? data?.selected_agent_category_key,
      };
      const hasMeta = Object.values(meta).some((value) => !!value);
      setActiveMeta(hasMeta ? meta : null);
      setMessages((prev) => [...prev, { role: "bot", text }]);
    } catch (e: any) {
      setMessages((prev) => [...prev, { role: "bot", text: `❌ Error: ${e?.message ?? "Unknown error"}` }]);
    } finally {
      setLoading(false);
      setTimeout(() => scrollRef.current?.scrollTo({ top: 9999, behavior: "smooth" }), 100);
    }
  };

  const handleClose = () => {
    setMessages([]);
    setInput("");
    setActiveMeta(null);
    onClose();
  };

  return (
    <Modal
      opened={opened}
      onClose={handleClose}
      title={
        <Group gap="xs">
          <IconRobot size={18} />
          <Text fw={600}>Test Agent{agentName ? `: ${agentName}` : ""}</Text>
        </Group>
      }
      size="lg"
    >
      <Stack gap="sm">
        {agentId && (
          <Alert color="blue" variant="light" p={8}>
            <Text size="xs">
              Messages will be sent with <strong>agent_id override</strong> — this agent will always be used regardless of intent detection.
            </Text>
          </Alert>
        )}
        {!agentId && (
          <Alert color="yellow" variant="light" p={8}>
            <Text size="xs">No agent_id set — the system will auto-select the best matching agent.</Text>
          </Alert>
        )}

        <ScrollArea h={340} viewportRef={scrollRef} offsetScrollbars>
          <Stack gap="xs" p="xs">
            {messages.length === 0 && (
              <Text size="sm" c="dimmed" ta="center" mt="xl">
                Send a message to test the agent…
              </Text>
            )}
            {messages.map((m, i) => (
              <Box
                key={i}
                p="xs"
                style={{
                  alignSelf: m.role === "user" ? "flex-end" : "flex-start",
                  background: m.role === "user" ? "var(--mantine-color-blue-1)" : "var(--mantine-color-gray-1)",
                  borderRadius: 8,
                  maxWidth: "85%",
                }}
              >
                <Text size="sm" style={{ whiteSpace: "pre-wrap" }}>
                  {m.text}
                </Text>
              </Box>
            ))}
            {loading && (
              <Box p="xs" style={{ alignSelf: "flex-start", background: "var(--mantine-color-gray-1)", borderRadius: 8 }}>
                <Loader size="xs" />
              </Box>
            )}
          </Stack>
        </ScrollArea>

        {activeMeta && (
          <Paper withBorder p="xs" bg="gray.0">
            <Text size="xs" fw={600} c="dimmed" mb={4}>
              Routing Meta
            </Text>
            <Text size="xs" c="dimmed">
              meta.active_agent_id: {activeMeta.active_agent_id ?? "-"}
            </Text>
            <Text size="xs" c="dimmed">
              meta.active_agent_name: {activeMeta.active_agent_name ?? "-"}
            </Text>
            <Text size="xs" c="dimmed">
              meta.active_agent_source: {activeMeta.active_agent_source ?? "-"}
            </Text>
            <Text size="xs" c="dimmed">
              meta.selected_agent_category_key: {activeMeta.selected_agent_category_key ?? "-"}
            </Text>
          </Paper>
        )}

        <Group gap="xs">
          <TextInput style={{ flex: 1 }} placeholder="Type a test message…" value={input} onChange={(e) => setInput(e.currentTarget.value)} onKeyDown={(e) => e.key === "Enter" && !e.shiftKey && send()} disabled={loading} />
          <ActionIcon size="lg" variant="filled" color="blue" onClick={send} loading={loading} disabled={!input.trim()}>
            <IconSend size={16} />
          </ActionIcon>
        </Group>
      </Stack>
    </Modal>
  );
}

// ── Main form ─────────────────────────────────────────────────────────────────

// Full prompt data type (includes prompt_value for preview)
export type PromptFull = { id: string; prompt_name: string; prompt_value: string };

// ── Prompt Preview Modal ──────────────────────────────────────────────────────

function PromptPreviewModal({ opened, onClose, prompt }: { opened: boolean; onClose: () => void; prompt: PromptFull | null }) {
  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title={
        <Group gap="xs">
          <IconEye size={16} />
          <Text fw={600}>{prompt?.prompt_name ?? "Prompt Preview"}</Text>
        </Group>
      }
      size="xl"
    >
      {prompt ? (
        <ScrollArea h={460} offsetScrollbars>
          <Text size="sm" style={{ whiteSpace: "pre-wrap", fontFamily: "monospace", lineHeight: 1.7 }}>
            {prompt.prompt_value}
          </Text>
        </ScrollArea>
      ) : (
        <Text c="dimmed" size="sm">
          No prompt selected.
        </Text>
      )}
    </Modal>
  );
}

// ── Create Prompt Inline Modal ────────────────────────────────────────────────

function CreatePromptModal({ opened, onClose, onCreated }: { opened: boolean; onClose: () => void; onCreated: (prompt: PromptFull) => void }) {
  const [name, setName] = useState("");
  const [value, setValue] = useState("");
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState<string | null>(null);

  const handleCreate = async () => {
    if (!name.trim() || !value.trim()) {
      setErr("Both fields are required.");
      return;
    }
    setSaving(true);
    setErr(null);
    try {
      const res = await createPrompt({ prompt_name: name.trim(), prompt_value: value.trim() });
      const created = res?.data ?? res;
      if (!created?.id) throw new Error("Unexpected response from server");
      onCreated({ id: created.id, prompt_name: created.prompt_name, prompt_value: created.prompt_value });
      setName("");
      setValue("");
      onClose();
    } catch (e: any) {
      setErr(e?.message ?? "Failed to create prompt");
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title={
        <Group gap="xs">
          <IconPlus size={16} />
          <Text fw={600}>Create New Prompt</Text>
        </Group>
      }
      size="lg"
    >
      <Stack gap="md">
        {err && (
          <Text c="red" size="sm">
            {err}
          </Text>
        )}
        <TextInput label="Prompt Name" placeholder="e.g. Accommodation Assistant v2" required value={name} onChange={(e) => setName(e.currentTarget.value)} />
        <Textarea label="Prompt Value" description="The system instruction sent to the AI model" placeholder="You are a helpful Karma Group resort assistant…" required autosize minRows={8} maxRows={20} value={value} onChange={(e) => setValue(e.currentTarget.value)} />
        <Group justify="flex-end">
          <Button variant="subtle" onClick={onClose} disabled={saving}>
            Cancel
          </Button>
          <Button onClick={handleCreate} loading={saving} disabled={!name.trim() || !value.trim()}>
            Save Prompt
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
}

export default function AgentForm({ mode, promptOptions: initialPromptOptions, allPrompts: initialAllPrompts = [], initial, onSubmit, manualOpened, onManualClose, agentId, isGlobal }: { mode: "create" | "edit"; promptOptions: PromptOption[]; allPrompts?: PromptFull[]; initial?: Partial<AgentFormValues>; onSubmit: (payload: { agent_name: string; prompt_id: string; embed_model: string; language_model: string; embed_dimension: number; category_key: string; is_active: boolean; csv_urls: string[]; tuning_parameters: Record<string, number> }) => Promise<any>; manualOpened?: boolean; onManualClose?: () => void; agentId?: string; isGlobal?: boolean }) {
  const navigate = useNavigate();
  const [saving, setSaving] = useState(false);
  const [makingGlobal, setMakingGlobal] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [internalOpen, { open: openInternal, close: closeInternal }] = useDisclosure(false);
  const [testOpened, { open: openTest, close: closeTest }] = useDisclosure(false);
  const [previewOpened, { open: openPreview, close: closePreview }] = useDisclosure(false);
  const [createPromptOpened, { open: openCreatePrompt, close: closeCreatePrompt }] = useDisclosure(false);
  const [deletePromptOpened, { open: openDeletePrompt, close: closeDeletePrompt }] = useDisclosure(false);
  const [isDeletingPrompt, setIsDeletingPrompt] = useState(false);
  const isManualOpen = manualOpened ?? internalOpen;
  const closeManual = onManualClose ?? closeInternal;
  const openManual = onManualClose ? () => {} : openInternal;
  const [isUploading, setIsUploading] = useState(false);

  // Local prompt list so user can add a new prompt inline without page reload
  const [promptOptions, setPromptOptions] = useState<PromptOption[]>(initialPromptOptions);
  const [allPrompts, setAllPrompts] = useState<PromptFull[]>(initialAllPrompts);

  const form = useForm<AgentFormValues>({
    initialValues: agentInitialValues(initial),
    validate: agentValidate as any,
    validateInputOnBlur: true,
    validateInputOnChange: true,
  });

  const selectedPromptId = form.values.prompt_id;
  const selectedPrompt = allPrompts.find((p) => p.id === selectedPromptId) ?? null;

  const handlePromptCreated = (newPrompt: PromptFull) => {
    setAllPrompts((prev) => [...prev, newPrompt]);
    setPromptOptions((prev) => [...prev, { value: newPrompt.id, label: newPrompt.prompt_name }]);
    form.setFieldValue("prompt_id", newPrompt.id);
  };

  const handleDeletePrompt = async () => {
    if (!selectedPromptId) return;
    setIsDeletingPrompt(true);
    try {
      await deletePrompt(selectedPromptId);
      setAllPrompts((prev) => prev.filter((p) => p.id !== selectedPromptId));
      setPromptOptions((prev) => prev.filter((p) => p.value !== selectedPromptId));
      form.setFieldValue("prompt_id", "");
      closeDeletePrompt();
    } finally {
      setIsDeletingPrompt(false);
    }
  };

  const handleSave = async (values: AgentFormValues) => {
    setSubmitError(null);
    setSaving(true);
    const numericTuning: Record<string, number> = {};
    for (const key in values.tuning) numericTuning[key] = Number(values.tuning[key]);
    const normalizedCategory = values.category_key.trim().toLowerCase();
    try {
      const res = await onSubmit({
        agent_name: values.agent_name.trim(),
        prompt_id: values.prompt_id,
        embed_model: values.embed_model.trim(),
        language_model: values.language_model.trim(),
        embed_dimension: Number(values.embed_dimension),
        category_key: normalizedCategory,
        is_active: values.is_active,
        csv_urls: values.csv_urls,
        tuning_parameters: numericTuning,
      });
      if (res && (res as any).success === false) {
        throw new Error((res as any).message || `Failed to ${mode === "create" ? "create" : "update"} agent.`);
      }
      notifications.show({
        title: mode === "create" ? "Agent created" : "Agent updated",
        message: mode === "create" ? "Agent was created successfully." : "Agent was updated successfully.",
        color: "green",
        autoClose: 3000,
      });
      navigate(-1);
    } catch (e: any) {
      const msg = e?.message || `Failed to ${mode === "create" ? "create" : "update"} agent.`;
      setSubmitError(msg);
      notifications.show({
        title: "Error",
        message: msg,
        color: "red",
        autoClose: 5000,
      });
    } finally {
      setSaving(false);
    }
  };

  const [globalConfirmOpened, { open: openGlobalConfirm, close: closeGlobalConfirm }] = useDisclosure(false);

  const handleMakeGlobal = () => {
    if (!agentId) return;
    openGlobalConfirm();
  };

  const confirmMakeGlobal = async () => {
    if (!agentId) return;
    setMakingGlobal(true);
    try {
      await makeAgentGlobal(agentId);
      window.location.reload();
    } catch (e: any) {
      setSubmitError(e?.message || "Failed to make agent global.");
      setMakingGlobal(false);
    }
  };

  const [togglingActive, setTogglingActive] = useState(false);
  const handleToggleActive = async (checked: boolean) => {
    form.setFieldValue("is_active", checked);
    if (mode === "edit" && agentId) {
      setTogglingActive(true);
      try {
        await toggleAgentActive(agentId);
      } catch (e: any) {
        // revert on failure
        form.setFieldValue("is_active", !checked);
        setSubmitError(e?.message || "Failed to toggle agent status.");
      } finally {
        setTogglingActive(false);
      }
    }
  };

  return (
    <>
      <ConfirmModal
        opened={globalConfirmOpened}
        onClose={closeGlobalConfirm}
        title="Promote to Global Agent"
        message="Promote this agent to Global Agent? The current global agent will be demoted."
        confirmLabel="Promote"
        confirmColor="yellow"
        onConfirm={confirmMakeGlobal}
      />
      <AgentQuickGuideModal opened={isManualOpen} onClose={closeManual} />
      <TestAgentModal opened={testOpened} onClose={closeTest} agentId={agentId} agentName={form.values.agent_name || undefined} />
      <PromptPreviewModal opened={previewOpened} onClose={closePreview} prompt={selectedPrompt} />
      <CreatePromptModal opened={createPromptOpened} onClose={closeCreatePrompt} onCreated={handlePromptCreated} />

      <Modal opened={deletePromptOpened} onClose={closeDeletePrompt} title={<Text fw={600}>Delete Prompt</Text>} centered>
        <Text size="sm" mb="lg">
          Are you sure you want to delete <strong>{selectedPrompt?.prompt_name}</strong>? This action cannot be undone.
        </Text>
        <Group justify="flex-end">
          <Button variant="default" onClick={closeDeletePrompt} disabled={isDeletingPrompt}>
            Cancel
          </Button>
          <Button color="red" loading={isDeletingPrompt} onClick={handleDeletePrompt}>
            Delete
          </Button>
        </Group>
      </Modal>

      <Paper withBorder radius="md" p="xl">
        <form onSubmit={form.onSubmit(handleSave)}>
          {/* ── Header: title + badges ─────────────────────────────────────────── */}
          <Group justify="space-between" mb="xs">
            <Group gap="xs" align="center">
              <Title order={3}>{mode === "create" ? "Create Agent" : "Edit Agent"}</Title>
              {isGlobal && (
                <Badge color="yellow" variant="light" leftSection={<IconStar size={12} />}>
                  Global Agent
                </Badge>
              )}
            </Group>
            {!onManualClose && (
              <Tooltip label="Quick guide">
                <ActionIcon variant="subtle" color="blue" onClick={openManual}>
                  <IconInfoCircle size={18} />
                </ActionIcon>
              </Tooltip>
            )}
          </Group>

          {/* ── Action bar ────────────────────────────────────────────────────── */}
          <Group justify="flex-end" mb="lg" pb="md" style={{ borderBottom: "1px solid var(--mantine-color-gray-2)" }}>
            {/* Right: all buttons */}
            <Group gap="sm" align="center">
              {mode === "edit" && (
                <Tooltip label="Send test messages to this agent">
                  <Button size="xs" variant="light" color="teal" leftSection={<IconPlayerPlay size={14} />} onClick={openTest}>
                    Test Agent
                  </Button>
                </Tooltip>
              )}
              {mode === "edit" && !isGlobal && (
                <Tooltip label="Promote this agent to be the global/main-router agent">
                  <Button
                    size="xs"
                    variant="light"
                    color="yellow"
                    leftSection={<IconStar size={14} />}
                    onClick={handleMakeGlobal}
                    loading={makingGlobal}
                  >
                    Mark as Global
                  </Button>
                </Tooltip>
              )}
              <Tooltip label={isGlobal ? "Global agent must always stay active" : form.values.is_active ? "Click to deactivate" : "Click to activate"}>
                <Switch
                  label={form.values.is_active ? "Active" : "Inactive"}
                  labelPosition="left"
                  size="sm"
                  color="green"
                  checked={form.values.is_active}
                  disabled={!!isGlobal || togglingActive}
                  onChange={(e) => handleToggleActive(e.currentTarget.checked)}
                  styles={{ label: { cursor: isGlobal ? "not-allowed" : "pointer", fontWeight: 500, fontSize: 13 } }}
                />
              </Tooltip>
              <Button
                size="xs"
                variant="subtle"
                leftSection={<IconArrowLeft size={14} />}
                onClick={() => navigate(-1)}
              >
                Back
              </Button>
              <Button
                size="xs"
                type="submit"
                loading={saving}
                disabled={saving || isUploading}
              >
                {isUploading ? "Uploading…" : mode === "create" ? "Save Agent" : "Update Agent"}
              </Button>
            </Group>
          </Group>

          {submitError && (
            <Text c="red" size="sm" mt="xs">
              {submitError}
            </Text>
          )}

          {/* Basic Info */}
          <Divider my="lg" label="Basic Info" />
          <Stack gap="md">
            <TextInput label="Agent Name" data-field="agent_name" required error={form.errors.agent_name} {...form.getInputProps("agent_name")} />

            {/* Prompt selector with eye preview + inline create */}
            <Stack gap={4}>
              <Group gap="xs" align="flex-end" wrap="nowrap">
                <Select style={{ flex: 1 }} label="Associated Prompt" description="System instruction this agent uses" data={promptOptions} data-field="prompt_id" searchable required error={form.errors.prompt_id} {...form.getInputProps("prompt_id")} />
                <Tooltip label={selectedPromptId ? "Preview prompt" : "Select a prompt first"} position="top">
                  <ActionIcon variant="light" color="blue" size="lg" mb={form.errors.prompt_id ? 22 : 0} disabled={!selectedPromptId} onClick={openPreview}>
                    <IconEye size={16} />
                  </ActionIcon>
                </Tooltip>
                <Tooltip label="Create a new prompt" position="top">
                  <ActionIcon variant="light" color="green" size="lg" mb={form.errors.prompt_id ? 22 : 0} onClick={openCreatePrompt}>
                    <IconPlus size={16} />
                  </ActionIcon>
                </Tooltip>
                <Tooltip label={selectedPromptId ? "Delete this prompt" : "Select a prompt first"} position="top">
                  <ActionIcon variant="light" color="red" size="lg" mb={form.errors.prompt_id ? 22 : 0} disabled={!selectedPromptId} onClick={openDeletePrompt}>
                    <IconTrash size={16} />
                  </ActionIcon>
                </Tooltip>
              </Group>
              {selectedPrompt && (
                <Text size="xs" c="dimmed" lineClamp={2} pl={2}>
                  📄 {selectedPrompt.prompt_value.slice(0, 120)}
                  {selectedPrompt.prompt_value.length > 120 ? "…" : ""}
                </Text>
              )}
            </Stack>
          </Stack>

          {/* Model Config */}
          <Divider my="lg" label="Model Configuration" />
          <Stack gap="md">
            <TextInput label="Embedding Model" placeholder="models/gemini-embedding-001" data-field="embed_model" required error={form.errors.embed_model} {...form.getInputProps("embed_model")} />
            <TextInput label="Language Model" placeholder="gemini-2.0-flash-lite" data-field="language_model" required error={form.errors.language_model} {...form.getInputProps("language_model")} />
            <NumberInput label="Embedding Dimension" placeholder="768" data-field="embed_dimension" min={1} required error={form.errors.embed_dimension} {...form.getInputProps("embed_dimension")} />
          </Stack>

          {/* Routing */}
          <Divider my="lg" label="Routing & Visibility" />
          <Stack gap="md">
            <TextInput label="Category Key" description="Must match a key in the domain_routing_keywords prompt (e.g. 'accommodation', 'maps'). The bot routes to this agent when the guest's message matches that domain's keywords." placeholder="general" data-field="category_key" required error={form.errors.category_key} {...form.getInputProps("category_key")} />
          </Stack>

          {/* Data Sources */}
          <Divider my="lg" label="Knowledge Base Files" />
          <Stack gap="md" data-field="csv_urls">
            <FileUploadField
              label="Data Source Files (CSV / Excel)"
              description="Upload one or more CSV or Excel files for this agent's knowledge base. Multiple files are supported. Leave empty to use the server default."
              value={form.values.csv_urls}
              onChange={(urls) => form.setFieldValue("csv_urls", urls)}
              onUploadingChange={setIsUploading}
            />
          </Stack>

          {/* Tuning */}
          <Divider my="xl" label="Tuning Parameters" />
          <SimpleGrid cols={3} spacing="lg" data-field="tuning">
            {REQUIRED_TUNING_KEYS.map((key) => {
              const config = TUNING_CONFIG[key as RequiredTuningKey];
              return <NumberInput key={key} label={key.replace(/_/g, " ")} description={config.description} step={config.step} decimalScale={getPrecision(config.step)} required {...form.getInputProps(`tuning.${key}`)} />;
            })}
          </SimpleGrid>

        </form>
      </Paper>
    </>
  );
}