import { useState, useRef, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ScrollArea } from "@/components/ui/scroll-area";
import { User, Loader2, Sparkles, ArrowUp, ChevronDown, Paperclip, Check, X, Square, Plus, Database, Wand2, Search, Zap, LayoutGrid, CheckCircle2, Table, XCircle } from "lucide-react";
import { api } from "@/lib/api";
import { type ChartSpec } from "@/store/visualizationStore";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeRaw from 'rehype-raw';
import { useLocation } from "react-router-dom";
import { InlineVisualizationCard } from "./InlineVisualizationCard";
import { useProjectStore } from "@/store/projectStore";

interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  awaitingFirstToken?: boolean;
  viz?: MessageViz;
}

interface MessageViz {
  sql: string;
  rows: unknown[];
  chartSpec: ChartSpec | null;
  canVisualize: boolean;
  reasoning?: string;
  error?: string | null;
}

interface ModelConfig {
  id: string;
  name?: string;
  model: string;
  provider: string;
  is_active: boolean;
}

interface DataFileContext {
  filename: string;
  url: string;
  columns?: string[];
  summary?: string;
}

interface Skill {
  id: string;
  name: string;
  description?: string;
  type: string;
}

interface SessionData {
  key: string;
  metadata?: {
    active_data_file?: DataFileContext | null;
    selected_data_source?: string | null;
    [key: string]: any;
  };
  messages: Array<{
    role: string;
    content: string;
    [key: string]: any;
  }>;
}

export function ChatInterface() {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState("");
  const [selectedDataSource, setSelectedDataSource] = useState<string>("");
  const [availableSkills, setAvailableSkills] = useState<Skill[]>([]);
  const [selectedSkillIds, setSelectedSkillIds] = useState<string[]>([]);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const scrollRef = useRef<HTMLDivElement>(null);
  const location = useLocation();
  const { currentProject } = useProjectStore();
  
  // Model selection state
  const [models, setModels] = useState<ModelConfig[]>([]);
  const [selectedModelId, setSelectedModelId] = useState<string>("");
  const [modelOpen, setModelOpen] = useState(false);
  
  // Data Source selection state
  const [availableDataSources, setAvailableDataSources] = useState<{id: string, name: string}[]>([]);

  // Try to parse active session from URL query
  const queryParams = new URLSearchParams(location.search);
  const activeSessionKey = queryParams.get("session") || "api:default";

  // File upload state
  const [attachedFile, setAttachedFile] = useState<DataFileContext | null>(null);
  const [activeDataFile, setActiveDataFile] = useState<DataFileContext | null>(null);
  const [isUploading, setIsUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const abortControllerRef = useRef<AbortController | null>(null);

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

  useEffect(() => {
    if (currentProject) {
      fetchDataSources();
    }
  }, [currentProject]);

  const fetchDataSources = async () => {
    if (!currentProject) return;
    try {
      const data = await api.get<Array<{id: number, name: string}>>(`/api/v1/datasources?project_id=${currentProject.id}`);
      const projectSources = data.map(d => ({ id: `ds:${d.id}`, name: d.name }));
      setAvailableDataSources(projectSources);
      if (selectedDataSource && !projectSources.find(ds => ds.id === selectedDataSource)) {
        setSelectedDataSource("");
        void syncSessionContext({ selected_data_source: null });
      }
    } catch (e) {
      console.error("Failed to fetch data sources", e);
    }
  };

  const syncSessionContext = async (payload: {
    active_data_file?: DataFileContext | null;
    selected_data_source?: string | null;
  }) => {
    try {
      await api.put(`/nanobot/sessions/${encodeURIComponent(activeSessionKey)}/context-file`, payload);
    } catch (e) {
      console.error("Failed to sync session context", e);
    }
  };

  const handleSelectDataSource = async (sourceId: string) => {
    setSelectedDataSource(sourceId);
    await syncSessionContext({ selected_data_source: sourceId });
  };

  const handleClearDataSource = async () => {
    setSelectedDataSource("");
    await syncSessionContext({ selected_data_source: null });
  };

  useEffect(() => {
    const fetchSessionData = async () => {
      setIsLoading(true);
      setSelectedSkillIds([]);
      try {
        const data = await api.get<SessionData>(`/nanobot/sessions/${activeSessionKey}`);
        if (data.messages && data.messages.length > 0) {
          const formattedMessages = data.messages.map((m, idx) => ({
            id: `${Date.now()}-${idx}`,
            role: m.role as 'user' | 'assistant',
            content: m.content,
            viz: m.viz ? buildMessageViz(m.viz) : undefined,
          }));
          setMessages(formattedMessages);
        } else {
          setMessages([]);
        }
        const restoredFile = data.metadata?.active_data_file || null;
        const restoredSource = data.metadata?.selected_data_source || "";
        setActiveDataFile(restoredFile);
        setSelectedDataSource(restoredSource);
        setAttachedFile(null);
      } catch (e) {
        console.error("Failed to fetch session messages", e);
        setMessages([]);
        setActiveDataFile(null);
        setSelectedDataSource("");
        setAttachedFile(null);
      } finally {
        setIsLoading(false);
      }
    };
    
    fetchSessionData();
  }, [activeSessionKey]);

  const fetchModels = async () => {
    try {
      const data = await api.get<ModelConfig[]>("/api/v1/llm");
      setModels(data);
      // Set default model if available
      const active = data.find(m => m.is_active);
      if (active) {
        setSelectedModelId(active.id);
      } else if (data.length > 0) {
        setSelectedModelId(data[0].id);
      }
    } catch (e) {
      console.error("Failed to fetch models", e);
    }
  };

  const currentModel = models.find(m => m.id === selectedModelId);
  
  const chartIntentPattern = /(图表|可视化|画图|作图|柱状图|折线图|饼图|趋势|分布|chart|plot|visuali[sz]e)/i;

  const buildMessageViz = (payload: {
    sql?: string;
    result?: unknown;
    error?: string | null;
    chart?: { chart_spec?: ChartSpec | null; reasoning?: string; can_visualize?: boolean; chart_type?: string } | null;
  }): MessageViz => {
    const rows = Array.isArray(payload.result) ? payload.result : [];
    const chart = payload.chart ?? undefined;
    const canVisualize = Boolean(chart?.can_visualize);
    const chartSpec = canVisualize ? (chart?.chart_spec ?? null) : null;
    return {
      sql: typeof payload.sql === "string" ? payload.sql : "",
      rows,
      chartSpec,
      canVisualize,
      reasoning: chart?.reasoning,
      error: payload.error ?? null,
    };
  };

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setIsUploading(true);
    const formData = new FormData();
    formData.append("file", file);

    try {
      const response = await fetch("/api/v1/upload/file", {
        method: "POST",
        body: formData,
        headers: {
          ...(localStorage.getItem("token") ? { Authorization: `Bearer ${localStorage.getItem("token")}` } : {}),
        }
      });

      if (!response.ok) {
        throw new Error("Upload failed");
      }

      const data = await response.json();
      const uploadedFile = {
        filename: file.name,
        url: data.url,
        columns: data.columns,
        summary: data.summary,
      };
      setAttachedFile(uploadedFile);
      setActiveDataFile(uploadedFile);
      setSelectedDataSource("");
      await syncSessionContext({ active_data_file: uploadedFile, selected_data_source: null });
    } catch (error) {
      console.error("File upload error:", error);
      // Could show a toast notification here
    } finally {
      setIsUploading(false);
      if (fileInputRef.current) {
        fileInputRef.current.value = "";
      }
    }
  };

  const handleRemoveFile = async () => {
    setAttachedFile(null);
    setActiveDataFile(null);
    await syncSessionContext({ active_data_file: null });
  };

  const selectedDataSourceName = availableDataSources.find(ds => ds.id === selectedDataSource)?.name || "";
  const selectedSkills = availableSkills.filter(skill => selectedSkillIds.includes(skill.id));

  const renderActiveSelections = () => {
    if (!selectedDataSource && selectedSkills.length === 0) return null;
    return (
      <div className="px-2 pt-2">
        <div className="flex flex-wrap gap-2">
          {selectedDataSource ? (
            <div className="px-3 py-1.5 rounded-full text-xs border flex items-center gap-1.5 bg-blue-50 text-blue-700 border-blue-200">
              <Database className="h-3.5 w-3.5" />
              {`数据源：${selectedDataSourceName}`}
            </div>
          ) : null}
          {selectedSkills.map((skill) => (
            <div
              key={skill.id}
              className="px-3 py-1.5 rounded-full text-xs border flex items-center gap-1.5 bg-orange-50 text-orange-700 border-orange-200"
            >
              <Wand2 className="h-3.5 w-3.5" />
              {`Skill：${skill.name}`}
            </div>
          ))}
        </div>
      </div>
    );
  };

  const renderFileCard = () => {
    const file = attachedFile || activeDataFile;
    if (!file) return null;
    return (
      <div className="px-2 pt-2">
        <div className="p-2.5 bg-white border border-zinc-100 rounded-2xl flex items-center gap-3 relative group/file shadow-sm max-w-[280px]">
          <div className="h-10 w-10 bg-emerald-600 rounded-xl flex items-center justify-center shrink-0">
            <Table className="h-6 w-6 text-white" />
          </div>
          <div className="flex-1 min-w-0 pr-6">
            <div className="text-sm font-bold text-zinc-900 truncate">{file.filename}</div>
            <div className="text-xs text-zinc-500">电子表格</div>
          </div>
          <button 
            onClick={handleRemoveFile}
            className="absolute top-1.5 right-1.5 h-5 w-5 rounded-full flex items-center justify-center transition-colors group/close"
          >
            <XCircle className="h-5 w-5 fill-zinc-900 text-white" />
          </button>
        </div>
      </div>
    );
  };

  useEffect(() => {
    const fetchSkills = async () => {
      try {
        let url = "/api/v1/skills";
        if (currentProject) {
          url += `?project_id=${currentProject.id}`;
        }
        const skills = await api.get<Skill[]>(url);
        setAvailableSkills(skills);
      } catch (err) {
        console.error("Failed to fetch skills:", err);
      }
    };
    fetchSkills();
  }, [currentProject]);

  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  }, [messages]);

  const handleForceStop = () => {
    const controller = abortControllerRef.current;
    if (!controller) return;
    controller.abort();
    setIsLoading(false);
    setMessages((prev) =>
      prev.map((msg) =>
        msg.awaitingFirstToken
          ? { ...msg, awaitingFirstToken: false, content: msg.content || "已中断输出" }
          : msg
      )
    );
  };

  const handleSend = async () => {
    if (!input.trim() || isLoading) return;
    
    const newMessage: Message = { id: Date.now().toString(), role: 'user', content: input };
    setMessages(prev => [...prev, newMessage]);
    setInput("");
    
    let messagePayload = newMessage.content;
    const currentAttachedFile = attachedFile;
    if (currentAttachedFile) {
      messagePayload = `[用户上传了文件: ${currentAttachedFile.filename}]\n[文件内容摘要: ${currentAttachedFile.summary || "无"}]\n[数据列: ${currentAttachedFile.columns?.join(", ") || "无"}]\n[文件下载链接: ${currentAttachedFile.url}]\n\n${newMessage.content}`;
      setAttachedFile(null);
    }
    
    const controller = new AbortController();
    abortControllerRef.current = controller;
    setIsLoading(true);
    
    try {
       const assistantId = (Date.now() + 1).toString();
       setMessages(prev => [...prev, {
          id: assistantId,
          role: "assistant",
          content: "",
          awaitingFirstToken: true
       }]);

       const token = localStorage.getItem("token");
       const effectiveModelId = selectedModelId || currentModel?.id || "";
       
      let source = selectedDataSource || "postgres";
       
       const useUploadSource = Boolean(currentAttachedFile?.url?.startsWith("local://"));
       if (useUploadSource) {
         source = "upload";
       }
       
       const fileUrl = useUploadSource ? (currentAttachedFile?.url || activeDataFile?.url) : undefined;
       const preferSqlChart = chartIntentPattern.test(messagePayload);
       const response = await fetch("/nanobot/chat/stream", {
         method: "POST",
         headers: {
           "Content-Type": "application/json",
           ...(token ? { Authorization: `Bearer ${token}` } : {}),
         },
         body: JSON.stringify({
             message: messagePayload,
             session_id: activeSessionKey,
             model_id: effectiveModelId,
             skill_ids: selectedSkillIds,
             source,
             prefer_sql_chart: preferSqlChart,
             file_url: fileUrl,
             route_mode: "auto",
           }),
         signal: controller.signal,
       });

       if (!response.ok || !response.body) {
         const err = await response.json().catch(() => ({}));
         throw new Error(err.detail || "流式响应失败");
       }

       const reader = response.body.getReader();
       const decoder = new TextDecoder("utf-8");
       let buffer = "";
       let streamedText = "";
       let streamedViz: MessageViz | null = null;

       while (true) {
         const { done, value } = await reader.read();
         if (done) break;
         buffer += decoder.decode(value, { stream: true });
         const events = buffer.split("\n\n");
         buffer = events.pop() || "";

         for (const eventBlock of events) {
           const line = eventBlock
             .split("\n")
             .find((item) => item.startsWith("data:"));
           if (!line) continue;
           const payloadText = line.slice(5).trim();
           if (!payloadText) continue;
          const payload = JSON.parse(payloadText) as {
            type: string;
            content?: string;
            sql?: string;
            result?: unknown;
            error?: string;
            chart?: { chart_spec?: ChartSpec | null; reasoning?: string; can_visualize?: boolean; chart_type?: string } | null;
          };

           if (payload.type === "delta" && payload.content) {
             streamedText = `${streamedText}${payload.content}`;
             setMessages((prev) =>
               prev.map((msg) =>
                  msg.id === assistantId ? { ...msg, content: streamedText, awaitingFirstToken: false } : msg
               )
             );
           }

           if (payload.type === "final" && payload.content) {
             streamedText = payload.content;
             setMessages((prev) =>
               prev.map((msg) =>
                 msg.id === assistantId ? { ...msg, content: payload.content || "", awaitingFirstToken: false, viz: streamedViz ?? msg.viz } : msg
               )
             );
           }

           if (payload.type === "error") {
             throw new Error(payload.content || "流式响应错误");
           }

          if (payload.type === "viz") {
            streamedViz = buildMessageViz(payload);
            setMessages((prev) =>
              prev.map((msg) =>
                 msg.id === assistantId ? { ...msg, viz: streamedViz || undefined } : msg
              )
            );
          }
         }
       }

       if (!streamedText) {
        const fallback = await api.post<{
          response: string;
          viz?: {
            sql?: string;
            result?: unknown;
            error?: string | null;
            chart?: { chart_spec?: ChartSpec | null; reasoning?: string; can_visualize?: boolean; chart_type?: string } | null;
          };
        }>("/nanobot/chat", {
           message: messagePayload,
           session_id: activeSessionKey,
           model_id: effectiveModelId,
           skill_ids: selectedSkillIds,
          source,
          prefer_sql_chart: preferSqlChart,
          file_url: fileUrl,
          route_mode: "auto",
         }, { signal: controller.signal });
        const fallbackViz = fallback.viz ? buildMessageViz(fallback.viz) : undefined;
         setMessages((prev) =>
           prev.map((msg) =>
           msg.id === assistantId ? { ...msg, content: fallback.response || "暂无回复", awaitingFirstToken: false, viz: fallbackViz } : msg
           )
         );
       }
    } catch (error: any) {
        if (error?.name === "AbortError" || String(error?.message || "").toLowerCase().includes("aborted")) {
          setMessages((prev) =>
            prev.map((msg) =>
              msg.awaitingFirstToken
                ? { ...msg, awaitingFirstToken: false, content: msg.content || "已中断输出" }
                : msg
            )
          );
          return;
        }
        setMessages(prev => [...prev, { 
            id: (Date.now() + 1).toString(), 
            role: 'assistant', 
            content: `Sorry, something went wrong: ${error.message}` 
        }]);
    } finally {
        if (abortControllerRef.current === controller) {
          abortControllerRef.current = null;
        }
        setIsLoading(false);
        window.dispatchEvent(new Event("nanobot:sessions-changed"));
    }
  };

  return (
    <div className="flex flex-col h-full bg-white relative">
      {/* Header with Model Selection */}
      <div className="px-4 py-3 flex items-center justify-between border-b border-zinc-100 bg-white/50 backdrop-blur-md sticky top-0 z-20">
        <Popover open={modelOpen} onOpenChange={setModelOpen}>
          <PopoverTrigger className="flex items-center gap-2 px-3 py-1.5 rounded-lg hover:bg-zinc-100 transition-colors group">
            <span className="font-semibold text-zinc-900">
              {selectedModelId ? models.find(m => m.id === selectedModelId)?.name || 'DataClaw' : 'DataClaw'}
            </span>
            <ChevronDown className="h-4 w-4 text-zinc-400 group-hover:text-zinc-600 transition-colors" />
          </PopoverTrigger>
          <PopoverContent className="w-[280px] p-0" align="start">
            <Command>
              <CommandInput placeholder="搜索模型..." />
              <CommandList className="max-h-[300px]">
                <CommandEmpty>未找到模型</CommandEmpty>
                <CommandGroup heading="可用模型">
                  {models.map((model) => (
                    <CommandItem
                      key={model.id}
                      onSelect={() => {
                        setSelectedModelId(model.id);
                        setModelOpen(false);
                      }}
                      className="flex items-center gap-2 py-2.5 cursor-pointer"
                    >
                      <div className="flex flex-col">
                        <span className="font-medium text-zinc-900">{model.name || model.model}</span>
                        <span className="text-xs text-zinc-400">{model.provider}</span>
                      </div>
                      <Check
                        className={cn(
                          "ml-auto h-4 w-4",
                          selectedModelId === model.id ? "opacity-100" : "opacity-0"
                        )}
                      />
                    </CommandItem>
                  ))}
                </CommandGroup>
              </CommandList>
            </Command>
          </PopoverContent>
        </Popover>
      </div>

      <ScrollArea className="flex-1 min-h-0">
        {/* Hidden file input available in all states */}
        <input
          type="file"
          ref={fileInputRef}
          className="hidden"
          accept=".csv,.xls,.xlsx"
          onChange={handleFileUpload}
        />
        <div className="min-h-full">
          {messages.length === 0 ? (
            <div className="h-full flex flex-col items-center justify-center pt-[20vh] px-4 pb-32">
              {/* Logo Area */}
              <div className="mb-16 flex items-center justify-center gap-4 select-none">
                <div className="text-[64px] leading-none animate-bounce-slow pb-3">
                  🦞
                </div>
                <h1 className="text-[56px] font-bold bg-clip-text text-transparent bg-gradient-to-r from-red-500 via-orange-500 to-amber-500 tracking-tight">
                  DataClaw
                </h1>
              </div>

              {/* Input Area */}
              <div className="w-full max-w-4xl px-4">
                <div className="relative group">
                  <div className="flex flex-col bg-white rounded-[26px] border border-zinc-200 shadow-[0_2px_12px_rgba(0,0,0,0.04)] transition-all duration-200">
                    {renderFileCard()}
                    {renderActiveSelections()}
                    <div className="flex items-center pl-2 pr-2 py-2">
                      <div className="flex items-center">
                        <Popover open={isMenuOpen} onOpenChange={setIsMenuOpen}>
                          <PopoverTrigger className="flex items-center justify-center h-9 w-9 rounded-full hover:bg-zinc-100 transition-colors text-zinc-500">
                            <Plus className="h-5 w-5" />
                          </PopoverTrigger>
                          <PopoverContent side="top" align="start" className="w-[480px] p-0 mb-2 overflow-hidden rounded-2xl border-zinc-200 shadow-xl">
                            <div className="flex divide-x divide-zinc-100">
                              {/* Left Column: Data Source */}
                              <div className="flex-1 p-3 bg-zinc-50/50">
                                <div className="text-[11px] font-semibold text-zinc-400 uppercase tracking-wider mb-2 px-2 flex items-center gap-1.5">
                                  <Database className="h-3 w-3" />
                                  数据源
                                </div>
                                <div className="space-y-0.5">
                                  {availableDataSources.map((ds) => (
                                    <button
                                      key={ds.id}
                                      onClick={() => {
                                        void handleSelectDataSource(ds.id);
                                      }}
                                      className={cn(
                                        "w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-sm transition-all duration-200",
                                        selectedDataSource === ds.id 
                                          ? "bg-white text-zinc-900 shadow-sm ring-1 ring-zinc-200" 
                                          : "text-zinc-600 hover:bg-white hover:shadow-sm"
                                      )}
                                    >
                                      <div className="flex items-center gap-2.5">
                                        <Database className={cn("h-4 w-4", selectedDataSource === ds.id ? "text-blue-500" : "text-zinc-400")} />
                                        <span className="font-medium">{ds.name}</span>
                                      </div>
                                      {selectedDataSource === ds.id && <CheckCircle2 className="h-4 w-4 text-blue-500" />}
                                    </button>
                                  ))}
                                  {selectedDataSource && (
                                    <div className="mt-2 pt-2 border-t border-zinc-100">
                                      <button
                                        onClick={() => {
                                          void handleClearDataSource();
                                        }}
                                        className="w-full py-1.5 text-[11px] text-zinc-400 hover:text-zinc-600 transition-colors flex items-center justify-center gap-1"
                                      >
                                        清除已选
                                      </button>
                                    </div>
                                  )}
                                </div>
                              </div>

                              {/* Right Column: Skills */}
                              <div className="flex-1 p-3 bg-white">
                                <div className="text-[11px] font-semibold text-zinc-400 uppercase tracking-wider mb-2 px-2 flex items-center gap-1.5">
                                  <Wand2 className="h-3 w-3" />
                                  Skills
                                </div>
                                <div className="space-y-0.5 max-h-[300px] overflow-y-auto pr-1">
                                  {availableSkills.length > 0 ? (
                                    availableSkills.map((skill) => {
                                      const isSelected = selectedSkillIds.includes(skill.id);
                                      return (
                                        <button
                                          key={skill.id}
                                          onClick={() => {
                                            setSelectedSkillIds((prev) =>
                                              isSelected
                                                ? prev.filter((id) => id !== skill.id)
                                                : [...prev, skill.id]
                                            );
                                          }}
                                          className={cn(
                                            "w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-sm transition-all duration-200",
                                            isSelected 
                                              ? "bg-white text-zinc-900 shadow-sm ring-1 ring-zinc-200" 
                                              : "text-zinc-600 hover:bg-white hover:shadow-sm"
                                          )}
                                        >
                                          <div className="flex items-center text-left">
                                            <span className="font-medium">{skill.name}</span>
                                          </div>
                                          {isSelected && <CheckCircle2 className="h-4 w-4 text-blue-500" />}
                                        </button>
                                      );
                                    })
                                  ) : (
                                    <div className="px-3 py-8 text-center">
                                      <Zap className="h-8 w-8 text-zinc-100 mx-auto mb-2" />
                                      <p className="text-xs text-zinc-400">暂无可用技能</p>
                                    </div>
                                  )}
                                </div>
                                {selectedSkillIds.length > 0 && (
                                  <div className="mt-2 pt-2 border-t border-zinc-100">
                                    <button 
                                      onClick={() => setSelectedSkillIds([])}
                                      className="w-full py-1.5 text-[11px] text-zinc-400 hover:text-zinc-600 transition-colors flex items-center justify-center gap-1"
                                    >
                                      清除已选 ({selectedSkillIds.length})
                                    </button>
                                  </div>
                                )}
                              </div>
                            </div>
                          </PopoverContent>
                        </Popover>
                      </div>

                      <input
                        type="text"
                        value={input}
                        onChange={(e) => setInput(e.target.value)}
                        onKeyDown={(e) => e.key === 'Enter' && !isLoading && handleSend()}
                        placeholder="有问题，尽管问"
                        className="flex-1 bg-transparent border-none focus:ring-0 text-lg px-3 py-2 text-zinc-900 placeholder:text-zinc-300 outline-none"
                        disabled={isLoading}
                      />

                      <div className="flex items-center gap-1">
                        <button
                          onClick={handleSend}
                          disabled={isLoading || !input.trim()}
                          className={cn(
                            "flex items-center justify-center h-10 w-10 rounded-full transition-all duration-200",
                            (input.trim() || attachedFile || activeDataFile) && !isLoading
                              ? "bg-zinc-900 text-white hover:bg-zinc-800 shadow-sm"
                              : "bg-zinc-100 text-zinc-300"
                          )}
                        >
                          {isLoading ? (
                            <Loader2 className="h-5 w-5 animate-spin" />
                          ) : (
                            <ArrowUp className="h-6 w-6" />
                          )}
                        </button>
                      </div>
                    </div>
                  </div>
                  <div className="mt-4 flex flex-wrap justify-center gap-2">
                    {/* Common Questions or suggestions could go here */}
                  </div>
                </div>
              </div>
            </div>
          ) : (
            <div className="max-w-3xl mx-auto px-4 py-8 space-y-8">
              {messages.map((msg) => (
                <div
                  key={msg.id}
                  className={`flex gap-4 ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
                >
                  {msg.role !== "user" && (
                    <div className="w-8 h-8 flex items-center justify-center shrink-0 mt-1">
                      <span className="text-2xl">🦞</span>
                    </div>
                  )}
                  <div
                    className={`rounded-2xl px-5 py-3.5 text-[15px] leading-relaxed max-w-[85%] shadow-sm ${
                      msg.role === "user"
                        ? "bg-zinc-100 text-zinc-800"
                        : "bg-white border border-zinc-100 text-zinc-700 overflow-hidden"
                    }`}
                  >
                    {msg.role === "assistant" ? (
                      msg.awaitingFirstToken && !msg.content ? (
                        <div className="flex items-center gap-2 text-zinc-500 text-sm py-1">
                          <Loader2 className="h-4 w-4 animate-spin" />
                          <span>模型思考中，请稍候...</span>
                        </div>
                      ) : (
                        <>
                          <div className="prose prose-sm prose-zinc max-w-none prose-p:leading-normal prose-p:my-2 prose-headings:my-3 prose-ul:my-2 prose-li:my-0.5 prose-pre:bg-zinc-50 prose-pre:text-zinc-800 prose-pre:border prose-pre:border-zinc-200">
                            <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
                              {msg.content}
                            </ReactMarkdown>
                          </div>
                          {msg.viz ? (
                            <div className="mt-3 pt-3 border-t border-zinc-100">
                              <InlineVisualizationCard viz={msg.viz} />
                            </div>
                          ) : null}
                        </>
                      )
                    ) : (
                      msg.content
                    )}
                  </div>
                  {msg.role === "user" && (
                    <div className="w-8 h-8 rounded-full bg-zinc-200 flex items-center justify-center text-zinc-500 shrink-0 mt-1">
                      <User className="h-4 w-4" />
                    </div>
                  )}
                </div>
              ))}
              <div ref={scrollRef} />
            </div>
          )}
        </div>
      </ScrollArea>
      
      {/* Floating Input for Chat State */}
      {messages.length > 0 && (
        <div className="px-4 pb-6 pt-3 border-t border-zinc-100 bg-white">
          <div className="relative group max-w-4xl mx-auto">
            <div className="flex flex-col bg-white rounded-[26px] border border-zinc-200 shadow-[0_2px_12px_rgba(0,0,0,0.04)] transition-all duration-200">
              {renderFileCard()}
              {renderActiveSelections()}
              <div className="flex items-center pl-2 pr-2 py-2">
                <div className="flex items-center">
                  <Popover open={isMenuOpen} onOpenChange={setIsMenuOpen}>
                    <PopoverTrigger className="flex items-center justify-center h-9 w-9 rounded-full hover:bg-zinc-100 transition-colors text-zinc-500">
                      <Plus className="h-5 w-5" />
                    </PopoverTrigger>
                    <PopoverContent side="top" align="start" className="w-[480px] p-0 mb-2 overflow-hidden rounded-2xl border-zinc-200 shadow-xl">
                      <div className="flex divide-x divide-zinc-100">
                        {/* Left Column: Data Source */}
                        <div className="flex-1 p-3 bg-zinc-50/50">
                          <div className="text-[11px] font-semibold text-zinc-400 uppercase tracking-wider mb-2 px-2 flex items-center gap-1.5">
                            <Database className="h-3 w-3" />
                            数据源
                          </div>
                          <div className="space-y-0.5">
                            {availableDataSources.map((ds) => (
                              <button
                                key={ds.id}
                                onClick={() => {
                                  void handleSelectDataSource(ds.id);
                                }}
                                className={cn(
                                  "w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-sm transition-all duration-200",
                                  selectedDataSource === ds.id 
                                    ? "bg-white text-zinc-900 shadow-sm ring-1 ring-zinc-200" 
                                    : "text-zinc-600 hover:bg-white hover:shadow-sm"
                                )}
                              >
                                <div className="flex items-center gap-2.5">
                                  <Database className={cn("h-4 w-4", selectedDataSource === ds.id ? "text-blue-500" : "text-zinc-400")} />
                                  <span className="font-medium">{ds.name}</span>
                                </div>
                                {selectedDataSource === ds.id && <CheckCircle2 className="h-4 w-4 text-blue-500" />}
                              </button>
                            ))}
                            {selectedDataSource && (
                              <div className="mt-2 pt-2 border-t border-zinc-100">
                                <button
                                  onClick={() => {
                                    void handleClearDataSource();
                                  }}
                                  className="w-full py-1.5 text-[11px] text-zinc-400 hover:text-zinc-600 transition-colors flex items-center justify-center gap-1"
                                >
                                  清除已选
                                </button>
                              </div>
                            )}
                          </div>
                        </div>

                        {/* Right Column: Skills */}
                        <div className="flex-1 p-3 bg-white">
                          <div className="text-[11px] font-semibold text-zinc-400 uppercase tracking-wider mb-2 px-2 flex items-center gap-1.5">
                            <Wand2 className="h-3 w-3" />
                            Skills
                          </div>
                          <div className="space-y-0.5 max-h-[300px] overflow-y-auto pr-1">
                            {availableSkills.length > 0 ? (
                              availableSkills.map((skill) => {
                                const isSelected = selectedSkillIds.includes(skill.id);
                                return (
                                  <button
                                    key={skill.id}
                                    onClick={() => {
                                      setSelectedSkillIds((prev) =>
                                        isSelected
                                          ? prev.filter((id) => id !== skill.id)
                                          : [...prev, skill.id]
                                      );
                                    }}
                                    className={cn(
                                      "w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-sm transition-all duration-200",
                                      isSelected 
                                        ? "bg-white text-zinc-900 shadow-sm ring-1 ring-zinc-200" 
                                        : "text-zinc-600 hover:bg-white hover:shadow-sm"
                                    )}
                                  >
                                    <div className="flex items-center text-left">
                                      <span className="font-medium">{skill.name}</span>
                                    </div>
                                    {isSelected && <CheckCircle2 className="h-4 w-4 text-blue-500" />}
                                  </button>
                                );
                              })
                            ) : (
                              <div className="px-3 py-8 text-center">
                                <Zap className="h-8 w-8 text-zinc-100 mx-auto mb-2" />
                                <p className="text-xs text-zinc-400">暂无可用技能</p>
                              </div>
                            )}
                          </div>
                          {selectedSkillIds.length > 0 && (
                            <div className="mt-2 pt-2 border-t border-zinc-100">
                              <button 
                                onClick={() => setSelectedSkillIds([])}
                                className="w-full py-1.5 text-[11px] text-zinc-400 hover:text-zinc-600 transition-colors flex items-center justify-center gap-1"
                              >
                                清除已选 ({selectedSkillIds.length})
                              </button>
                            </div>
                          )}
                        </div>
                      </div>
                    </PopoverContent>
                  </Popover>
                </div>

                <input
                  type="text"
                  value={input}
                  onChange={(e) => setInput(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && !isLoading && handleSend()}
                  placeholder="有问题，尽管问"
                  className="flex-1 bg-transparent border-none focus:ring-0 text-lg px-3 py-2 text-zinc-900 placeholder:text-zinc-300 outline-none"
                  disabled={isLoading}
                />

                <div className="flex items-center gap-1">
                  <button
                    onClick={isLoading ? handleForceStop : handleSend}
                    disabled={isLoading ? false : !input.trim()}
                    className={cn(
                      "flex items-center justify-center h-10 w-10 rounded-full transition-all duration-200",
                      (input.trim() || isLoading)
                        ? (isLoading ? "bg-red-600 text-white hover:bg-red-700" : "bg-zinc-900 text-white hover:bg-zinc-800")
                        : "bg-zinc-100 text-zinc-300"
                    )}
                  >
                    {isLoading ? (
                      <Square className="h-4 w-4" />
                    ) : (
                      <ArrowUp className="h-6 w-6" />
                    )}
                  </button>
                </div>
              </div>
            </div>
            <div className="mt-2 flex justify-center">
              <p className="text-[11px] text-zinc-400">
                DataClaw 可能会出错。请核查重要信息。
              </p>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
