"use client";

import { useState, useEffect, useCallback } from "react";
import { ChevronDown, ChevronRight, RefreshCw, BookOpen } from "lucide-react";
import { API_BASE_URL } from "@/lib/config";
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
} from "@/components/ui/sheet";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";

type MCPTool = {
  name: string;
  description: string | null;
  input_schema: Record<string, unknown>;
  server_name: string;
};

type MCPServer = {
  name: string;
  config: {
    transport: string;
    enabled: boolean;
    [key: string]: unknown;
  };
  status: "connecting" | "connected" | "disconnected" | "error";
  tools: MCPTool[];
  error: string | null;
  connected_at: string | null;
};

type SkillInfo = {
  name: string;
  description: string;
  scripts: string[];
  references: string[];
  enabled: boolean;
};

type Props = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

const STATUS_DOT: Record<MCPServer["status"], string> = {
  connected: "bg-emerald-500 shadow-[0_0_6px_theme(colors.emerald.500)]",
  connecting: "bg-amber-500 animate-pulse shadow-[0_0_6px_theme(colors.amber.500)]",
  disconnected: "bg-zinc-500",
  error: "bg-red-500 shadow-[0_0_6px_theme(colors.red.500)]",
};

export function MCPToolsPanel({ open, onOpenChange }: Props) {
  const [servers, setServers] = useState<MCPServer[]>([]);
  const [skills, setSkills] = useState<SkillInfo[]>([]);
  const [expanded, setExpanded] = useState<Set<string>>(new Set());
  const [loading, setLoading] = useState(false);
  const [toggling, setToggling] = useState<Set<string>>(new Set());

  const fetchServers = useCallback(async () => {
    try {
      setLoading(true);
      const [serversRes, skillsRes] = await Promise.allSettled([
        fetch(`${API_BASE_URL}/api/mcp/servers`),
        fetch(`${API_BASE_URL}/api/skills/`),
      ]);
      if (serversRes.status === "fulfilled" && serversRes.value.ok) {
        setServers(await serversRes.value.json());
      }
      if (skillsRes.status === "fulfilled" && skillsRes.value.ok) {
        setSkills(await skillsRes.value.json());
      }
    } catch {
      // silently fail on network errors
    } finally {
      setLoading(false);
    }
  }, []);

  // Fetch on open + 5s interval
  useEffect(() => {
    if (!open) return;
    fetchServers();
    const interval = setInterval(fetchServers, 5000);
    return () => clearInterval(interval);
  }, [open, fetchServers]);

  const toggleServer = async (name: string, enabled: boolean) => {
    setToggling((prev) => new Set(prev).add(name));
    try {
      const res = await fetch(`${API_BASE_URL}/api/mcp/servers/${name}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ enabled }),
      });
      if (res.ok) {
        await fetchServers();
      }
    } catch {
      // silently fail
    } finally {
      setToggling((prev) => {
        const next = new Set(prev);
        next.delete(name);
        return next;
      });
    }
  };

  const toggleExpand = (name: string) => {
    setExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(name)) next.delete(name);
      else next.add(name);
      return next;
    });
  };

  const toggleSkill = async (name: string, enabled: boolean) => {
    setToggling((prev) => new Set(prev).add(`skill:${name}`));
    try {
      const res = await fetch(`${API_BASE_URL}/api/skills/${encodeURIComponent(name)}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ enabled }),
      });
      if (res.ok) {
        await fetchServers();
      }
    } catch {
      // silently fail
    } finally {
      setToggling((prev) => {
        const next = new Set(prev);
        next.delete(`skill:${name}`);
        return next;
      });
    }
  };

  const totalTools = servers.reduce((sum, s) => sum + s.tools.length, 0);
  const enabledSkills = skills.filter((s) => s.enabled);

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent
        side="right"
        className="bg-background/80 backdrop-blur-2xl border-foreground/10 w-[380px] sm:max-w-[380px]"
      >
        <SheetHeader className="border-b border-foreground/5 pb-4">
          <SheetTitle className="text-xs font-black uppercase tracking-[0.2em] text-foreground/90">
            Tools & Skills
          </SheetTitle>
          <SheetDescription className="text-[10px] uppercase tracking-widest text-muted-foreground/50 flex items-center justify-between">
            <span>
              {servers.length} servers / {totalTools} tools / {enabledSkills.length} skills
            </span>
            <Button
              variant="ghost"
              size="icon"
              className="h-6 w-6"
              onClick={fetchServers}
              disabled={loading}
            >
              <RefreshCw
                size={12}
                className={cn(loading && "animate-spin")}
              />
            </Button>
          </SheetDescription>
        </SheetHeader>

        <ScrollArea className="flex-1 -mx-4 px-4">
          <div className="space-y-2 py-2">
            {servers.length === 0 && skills.length === 0 && !loading && (
              <p className="text-xs text-muted-foreground/50 text-center py-8">
                등록된 MCP 서버 및 스킬이 없습니다.
              </p>
            )}

            {servers.map((server) => {
              const isExpanded = expanded.has(server.name);
              const isToggling = toggling.has(server.name);

              return (
                <div
                  key={server.name}
                  className="rounded-xl border border-foreground/5 bg-foreground/[0.02] overflow-hidden"
                >
                  {/* Server header */}
                  <div className="flex items-center gap-3 px-4 py-3">
                    <button
                      type="button"
                      onClick={() => toggleExpand(server.name)}
                      className="flex items-center gap-3 flex-1 min-w-0 text-left"
                    >
                      <div
                        className={cn(
                          "w-2 h-2 rounded-full shrink-0",
                          STATUS_DOT[server.status]
                        )}
                      />
                      <div className="min-w-0 flex-1">
                        <div className="text-xs font-bold text-foreground/90 truncate">
                          {server.name}
                        </div>
                        <div className="text-[10px] text-muted-foreground/50">
                          {server.config.transport}
                          {server.status === "connected" &&
                            ` · ${server.tools.length} tools`}
                          {server.status === "error" && (
                            <span className="text-red-400 ml-1">
                              {server.error}
                            </span>
                          )}
                        </div>
                      </div>
                      {isExpanded ? (
                        <ChevronDown size={14} className="text-muted-foreground/30 shrink-0" />
                      ) : (
                        <ChevronRight size={14} className="text-muted-foreground/30 shrink-0" />
                      )}
                    </button>
                    <Switch
                      size="sm"
                      checked={server.config.enabled}
                      disabled={isToggling}
                      onCheckedChange={(checked) =>
                        toggleServer(server.name, checked)
                      }
                    />
                  </div>

                  {/* Expanded tool list */}
                  {isExpanded && server.tools.length > 0 && (
                    <div className="border-t border-foreground/5 px-4 py-2 space-y-1">
                      {server.tools.map((tool) => (
                        <div
                          key={tool.name}
                          className="py-1.5 px-2 rounded-lg hover:bg-foreground/5 transition-colors"
                        >
                          <div className="text-[11px] font-mono font-bold text-foreground/70">
                            {tool.name}
                          </div>
                          {tool.description && (
                            <div className="text-[10px] text-muted-foreground/40 leading-tight mt-0.5 line-clamp-2">
                              {tool.description}
                            </div>
                          )}
                        </div>
                      ))}
                    </div>
                  )}

                  {isExpanded && server.tools.length === 0 && server.status === "connected" && (
                    <div className="border-t border-foreground/5 px-4 py-3">
                      <p className="text-[10px] text-muted-foreground/30 text-center">
                        도구 없음
                      </p>
                    </div>
                  )}
                </div>
              );
            })}

            {/* Skills Section */}
            {skills.length > 0 && (
              <>
                <div className="pt-4 pb-1 px-1">
                  <span className="text-[9px] font-black uppercase tracking-[0.2em] text-muted-foreground/40 flex items-center gap-2">
                    <BookOpen size={10} />
                    Agent Skills
                  </span>
                </div>
                {skills.map((skill) => {
                  const isSkillToggling = toggling.has(`skill:${skill.name}`);
                  return (
                    <div
                      key={skill.name}
                      className="rounded-xl border border-foreground/5 bg-foreground/[0.02] overflow-hidden"
                    >
                      <div className="flex items-center gap-3 px-4 py-3">
                        <div
                          className={cn(
                            "w-2 h-2 rounded-full shrink-0",
                            skill.enabled
                              ? "bg-emerald-500 shadow-[0_0_6px_theme(colors.emerald.500)]"
                              : "bg-zinc-500"
                          )}
                        />
                        <div className="min-w-0 flex-1">
                          <div className="text-xs font-bold text-foreground/90 truncate">
                            {skill.name}
                          </div>
                          <div className="text-[10px] text-muted-foreground/50 line-clamp-1">
                            {skill.description}
                            {` · ${skill.scripts.length}s / ${skill.references.length}r`}
                          </div>
                        </div>
                        <Switch
                          size="sm"
                          checked={skill.enabled}
                          disabled={isSkillToggling}
                          onCheckedChange={(checked) =>
                            toggleSkill(skill.name, checked)
                          }
                        />
                      </div>
                    </div>
                  );
                })}
              </>
            )}
          </div>
        </ScrollArea>
      </SheetContent>
    </Sheet>
  );
}
