"use client";

import { useState, useRef, useEffect, useCallback } from "react";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Send,
  Loader2,
  Wrench,
  Bot,
  User,
  RotateCcw,
  ChevronDown,
  ChevronUp,
  Sparkles,
} from "lucide-react";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface Message {
  role: "user" | "assistant";
  content: string;
  toolCalls?: string[];
  turns?: number;
  model?: string;
  reasoning?: string | null;
  error?: boolean;
}

interface OrchestratorChatProps {
  projectId: string;
  projectName?: string;
  placeholder?: string;
}

// ---------------------------------------------------------------------------
// Friendly labels for tool call names
// ---------------------------------------------------------------------------

const TOOL_LABELS: Record<string, string> = {
  spawn_agent: "Dispatched agent",
  get_job_status: "Checked job",
  list_repos: "Listed repos",
  list_all_issues: "Checked issues",
  list_all_apps: "Checked deployments",
  get_app_status: "Checked app status",
  read_repo_file: "Read file",
  deploy_app: "Triggered deploy",
  gitea_create_issue: "Created issue",
  gitea_list_issues: "Listed issues",
  gitea_close_issue: "Closed issue",
  gitea_comment_issue: "Added comment",
  save_memory: "Saved to memory",
};

function friendlyToolName(raw: string): string {
  return TOOL_LABELS[raw] ?? raw.replace(/_/g, " ");
}

// ---------------------------------------------------------------------------
// Suggestion chips shown before the first message
// ---------------------------------------------------------------------------

const SUGGESTIONS = [
  "What's the current status of this project?",
  "Check if there are any open issues or PRs",
  "What was the last deployment?",
  "Write a quick summary of what's been built so far",
];

// ---------------------------------------------------------------------------
// Single message bubble
// ---------------------------------------------------------------------------

function MessageBubble({ msg }: { msg: Message }) {
  const [showReasoning, setShowReasoning] = useState(false);
  const isUser = msg.role === "user";

  return (
    <div className={`flex gap-3 ${isUser ? "flex-row-reverse" : ""}`}>
      {/* Avatar */}
      <div
        className={`shrink-0 w-7 h-7 rounded-full flex items-center justify-center mt-0.5
          ${isUser
            ? "bg-primary text-primary-foreground"
            : "bg-muted border border-border"
          }`}
      >
        {isUser ? <User className="h-3.5 w-3.5" /> : <Bot className="h-3.5 w-3.5" />}
      </div>

      {/* Bubble */}
      <div className={`flex-1 max-w-[85%] space-y-1.5 ${isUser ? "items-end flex flex-col" : ""}`}>
        <div
          className={`rounded-2xl px-4 py-3 text-sm leading-relaxed whitespace-pre-wrap
            ${isUser
              ? "bg-primary text-primary-foreground rounded-tr-sm"
              : msg.error
                ? "bg-destructive/10 text-destructive border border-destructive/20 rounded-tl-sm"
                : "bg-muted/60 border border-border rounded-tl-sm"
            }`}
        >
          {msg.content}
        </div>

        {/* Tool calls & meta */}
        {!isUser && (
          <div className="flex flex-wrap items-center gap-1.5 px-1">
            {msg.toolCalls && msg.toolCalls.length > 0 && (
              <div className="flex flex-wrap gap-1">
                {/* Deduplicate tool calls before rendering */}
                {[...new Set(msg.toolCalls)].map((t, i) => (
                  <span
                    key={i}
                    className="inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-muted border border-border text-muted-foreground"
                  >
                    <Wrench className="h-2.5 w-2.5 shrink-0" />
                    {friendlyToolName(t)}
                  </span>
                ))}
              </div>
            )}
            {msg.reasoning && (
              <button
                onClick={() => setShowReasoning(v => !v)}
                className="inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors"
              >
                <Sparkles className="h-2.5 w-2.5" />
                reasoning
                {showReasoning ? <ChevronUp className="h-2.5 w-2.5" /> : <ChevronDown className="h-2.5 w-2.5" />}
              </button>
            )}
            {msg.model && msg.model !== "unknown" && (
              <span className="text-[10px] text-muted-foreground/60 ml-auto">
                {msg.model.includes("glm") ? "GLM-5" : msg.model.includes("gemini") ? "Gemini" : msg.model}
              </span>
            )}
          </div>
        )}

        {/* Reasoning panel */}
        {!isUser && showReasoning && msg.reasoning && (
          <div className="mx-1 rounded-lg border border-border/50 bg-muted/30 px-3 py-2 text-[11px] text-muted-foreground leading-relaxed font-mono max-h-40 overflow-y-auto">
            {msg.reasoning}
          </div>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Typing indicator
// ---------------------------------------------------------------------------

function TypingIndicator() {
  return (
    <div className="flex gap-3">
      <div className="shrink-0 w-7 h-7 rounded-full bg-muted border border-border flex items-center justify-center">
        <Bot className="h-3.5 w-3.5" />
      </div>
      <div className="bg-muted/60 border border-border rounded-2xl rounded-tl-sm px-4 py-3">
        <div className="flex gap-1 items-center h-4">
          {[0, 1, 2].map(i => (
            <div
              key={i}
              className="w-1.5 h-1.5 rounded-full bg-muted-foreground/50 animate-bounce"
              style={{ animationDelay: `${i * 0.15}s` }}
            />
          ))}
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------

export function OrchestratorChat({
  projectId,
  projectName,
  placeholder = "Ask your AI team anything…",
}: OrchestratorChatProps) {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState("");
  const [loading, setLoading] = useState(false);
  const bottomRef = useRef<HTMLDivElement>(null);
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const hasMessages = messages.length > 0;

  const scrollToBottom = useCallback(() => {
    bottomRef.current?.scrollIntoView({ behavior: "smooth" });
  }, []);

  useEffect(() => {
    scrollToBottom();
  }, [messages, loading]);

  const sendMessage = useCallback(
    async (text: string) => {
      const trimmed = text.trim();
      if (!trimmed || loading) return;

      setInput("");
      setMessages(prev => [...prev, { role: "user", content: trimmed }]);
      setLoading(true);

      try {
        const res = await fetch(`/api/projects/${projectId}/agent-chat`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ message: trimmed }),
        });

        const data = await res.json();

        if (!res.ok) {
          setMessages(prev => [
            ...prev,
            { role: "assistant", content: data.error ?? "Something went wrong.", error: true },
          ]);
        } else {
          setMessages(prev => [
            ...prev,
            {
              role: "assistant",
              content: data.reply || "(no reply)",
              toolCalls: data.toolCalls,
              turns: data.turns,
              model: data.model,
              reasoning: data.reasoning,
            },
          ]);
        }
      } catch (err) {
        setMessages(prev => [
          ...prev,
          {
            role: "assistant",
            content: err instanceof Error ? err.message : "Network error — is the agent runner online?",
            error: true,
          },
        ]);
      } finally {
        setLoading(false);
        setTimeout(() => textareaRef.current?.focus(), 50);
      }
    },
    [projectId, loading]
  );

  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      sendMessage(input);
    }
  };

  const clearChat = async () => {
    setMessages([]);
    try {
      await fetch(`/api/projects/${projectId}/agent-chat`, { method: "DELETE" });
    } catch { /* best-effort */ }
  };

  return (
    <div className="flex flex-col rounded-xl border border-border bg-background overflow-hidden shadow-sm">

      {/* Header */}
      <div className="flex items-center justify-between px-4 py-3 border-b border-border bg-muted/20">
        <div className="flex items-center gap-2">
          <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
          <span className="text-sm font-medium">
            {projectName ? `${projectName} AI` : "Project AI"}
          </span>
          <Badge variant="outline" className="text-[10px] h-4 px-1.5">GLM-5</Badge>
        </div>
        {hasMessages && (
          <Button
            variant="ghost"
            size="sm"
            onClick={clearChat}
            className="h-7 text-xs text-muted-foreground"
          >
            <RotateCcw className="h-3 w-3 mr-1" />
            Clear
          </Button>
        )}
      </div>

      {/* Messages */}
      <div className="flex-1 min-h-0">
        {!hasMessages ? (
          /* Empty state — Lovable-style centered prompt */
          <div className="flex flex-col items-center justify-center px-6 py-10 gap-6 text-center">
            <div>
              <p className="text-lg font-semibold">What should we build?</p>
              <p className="text-sm text-muted-foreground mt-1">
                Your AI team is ready. Ask them anything about this project.
              </p>
            </div>
            <div className="flex flex-wrap justify-center gap-2 max-w-lg">
              {SUGGESTIONS.map(s => (
                <button
                  key={s}
                  onClick={() => sendMessage(s)}
                  className="text-xs px-3 py-1.5 rounded-full border border-border bg-muted/40 hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
                >
                  {s}
                </button>
              ))}
            </div>
          </div>
        ) : (
          <ScrollArea className="h-[360px]">
            <div className="px-4 py-4 space-y-5">
              {messages.map((msg, i) => (
                <MessageBubble key={i} msg={msg} />
              ))}
              {loading && <TypingIndicator />}
              <div ref={bottomRef} />
            </div>
          </ScrollArea>
        )}
      </div>

      {/* Input */}
      <div className="border-t border-border px-3 py-3 bg-muted/10">
        <div className="flex gap-2 items-end">
          <Textarea
            ref={textareaRef}
            value={input}
            onChange={e => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder={placeholder}
            rows={1}
            className="resize-none min-h-[40px] max-h-[120px] flex-1 text-sm bg-background border-border focus-visible:ring-1 rounded-xl"
            style={{ fieldSizing: "content" } as React.CSSProperties}
            disabled={loading}
          />
          <Button
            size="icon"
            onClick={() => sendMessage(input)}
            disabled={!input.trim() || loading}
            className="h-10 w-10 shrink-0 rounded-xl"
          >
            {loading ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Send className="h-4 w-4" />
            )}
          </Button>
        </div>
        <p className="text-[10px] text-muted-foreground/50 mt-1.5 pl-1">
          Enter to send · Shift+Enter for newline
        </p>
      </div>
    </div>
  );
}
