"use client";

import { useState } from "react";
import { Plus, FileJson } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import type { MCPServerConfig } from "@/lib/api/mcp";

const JSON_PLACEHOLDER = `{
  "my-server": {
    "transport": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-everything"],
    "enabled": true
  }
}`;

type AddServerDialogProps = {
  onAdd: (name: string, config: MCPServerConfig) => Promise<void>;
};

export function AddServerDialog({ onAdd }: AddServerDialogProps) {
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const [tab, setTab] = useState("form");

  // Form mode state
  const [transport, setTransport] = useState<MCPServerConfig["transport"]>("stdio");
  const [name, setName] = useState("");
  const [command, setCommand] = useState("");
  const [args, setArgs] = useState("");
  const [env, setEnv] = useState("");
  const [url, setUrl] = useState("");
  const [headers, setHeaders] = useState("");

  // JSON mode state
  const [jsonInput, setJsonInput] = useState("");
  const [jsonError, setJsonError] = useState<string | null>(null);

  const reset = () => {
    setTransport("stdio");
    setName("");
    setCommand("");
    setArgs("");
    setEnv("");
    setUrl("");
    setHeaders("");
    setJsonInput("");
    setJsonError(null);
    setTab("form");
  };

  const handleFormSubmit = async () => {
    if (!name.trim()) return;
    setLoading(true);
    try {
      const config: MCPServerConfig = { transport, enabled: true };
      if (transport === "stdio") {
        config.command = command.trim();
        if (args.trim()) config.args = args.split(",").map((a) => a.trim()).filter(Boolean);
        if (env.trim()) {
          config.env = {};
          for (const line of env.split("\n")) {
            const [k, ...rest] = line.split("=");
            if (k?.trim()) config.env[k.trim()] = rest.join("=").trim();
          }
        }
      } else {
        config.url = url.trim();
        if (headers.trim()) {
          config.headers = {};
          for (const line of headers.split("\n")) {
            const [k, ...rest] = line.split(":");
            if (k?.trim()) config.headers[k.trim()] = rest.join(":").trim();
          }
        }
      }
      await onAdd(name.trim(), config);
      reset();
      setOpen(false);
    } catch (err) {
      console.error("Failed to add server:", err);
    } finally {
      setLoading(false);
    }
  };

  const handleJsonSubmit = async () => {
    setJsonError(null);
    let parsed: Record<string, unknown>;
    try {
      parsed = JSON.parse(jsonInput);
    } catch {
      setJsonError("유효하지 않은 JSON 형식입니다.");
      return;
    }

    // Support both {"mcpServers": {...}} wrapper and direct {"name": {...}} format
    const servers: Record<string, unknown> =
      parsed.mcpServers && typeof parsed.mcpServers === "object"
        ? (parsed.mcpServers as Record<string, unknown>)
        : parsed;

    const entries = Object.entries(servers);
    if (entries.length === 0) {
      setJsonError("서버 설정이 비어 있습니다.");
      return;
    }

    setLoading(true);
    try {
      for (const [serverName, rawConfig] of entries) {
        const cfg = rawConfig as Record<string, unknown>;
        const config: MCPServerConfig = {
          transport: (cfg.transport as MCPServerConfig["transport"]) || "stdio",
          enabled: cfg.enabled !== false,
        };
        if (cfg.command) config.command = cfg.command as string;
        if (cfg.args) config.args = cfg.args as string[];
        if (cfg.env) config.env = cfg.env as Record<string, string>;
        if (cfg.url) config.url = cfg.url as string;
        if (cfg.headers) config.headers = cfg.headers as Record<string, string>;

        await onAdd(serverName, config);
      }
      reset();
      setOpen(false);
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : "서버 등록에 실패했습니다.";
      setJsonError(message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button className="h-12 rounded-none px-8 flex gap-3 bg-primary text-primary-foreground font-black uppercase tracking-widest shadow-[0_8px_20px_-5px_rgba(var(--primary),0.3)] hover:translate-y-[-1px] transition-all">
          <Plus className="w-5 h-5" />
          Add Server
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-[600px] bg-sidebar border-foreground/10 text-foreground p-0 overflow-hidden max-h-[90vh] overflow-y-auto">
        <div className="h-1.5 w-full bg-[repeating-linear-gradient(45deg,var(--primary),var(--primary)_10px,transparent_10px,transparent_20px)]" />
        <div className="p-8 space-y-6">
          <DialogHeader>
            <DialogTitle className="text-3xl font-black uppercase tracking-tighter text-foreground">Add MCP Server</DialogTitle>
            <DialogDescription className="text-foreground/60 font-medium uppercase text-[10px] tracking-widest pt-2">
              Register a new MCP server to the Nexus Agent platform.
            </DialogDescription>
          </DialogHeader>

          <Tabs value={tab} onValueChange={setTab}>
            <TabsList className="w-full bg-foreground/5 border border-foreground/10 rounded-none h-11">
              <TabsTrigger value="form" className="flex-1 rounded-none text-[10px] font-black uppercase tracking-widest data-[state=active]:bg-primary/20 data-[state=active]:text-primary">
                Form
              </TabsTrigger>
              <TabsTrigger value="json" className="flex-1 rounded-none text-[10px] font-black uppercase tracking-widest data-[state=active]:bg-primary/20 data-[state=active]:text-primary">
                <FileJson className="w-3.5 h-3.5 mr-1.5" />
                JSON
              </TabsTrigger>
            </TabsList>

            {/* ===== Form Mode ===== */}
            <TabsContent value="form" className="mt-6">
              <div className="grid gap-6">
                <div className="grid gap-3">
                  <Label className="text-[10px] font-black uppercase tracking-widest text-primary">Server Name</Label>
                  <Input
                    placeholder="e.g. my-mcp-server"
                    className="bg-black/20 border-foreground/10 h-11 text-sm font-mono"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                  />
                </div>

                <div className="grid gap-3">
                  <Label className="text-[10px] font-black uppercase tracking-widest text-primary">Transport Type</Label>
                  <Select value={transport} onValueChange={(v) => setTransport(v as MCPServerConfig["transport"])}>
                    <SelectTrigger className="bg-black/20 border-foreground/10 h-11 text-sm font-mono">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent className="bg-popover border-foreground/10">
                      <SelectItem value="stdio">stdio</SelectItem>
                      <SelectItem value="sse">sse</SelectItem>
                      <SelectItem value="streamable-http">streamable-http</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                {transport === "stdio" ? (
                  <>
                    <div className="grid gap-3">
                      <Label className="text-[10px] font-black uppercase tracking-widest text-primary">Command</Label>
                      <Input
                        placeholder="e.g. npx, uvx, node"
                        className="bg-black/20 border-foreground/10 h-11 text-xs font-mono"
                        value={command}
                        onChange={(e) => setCommand(e.target.value)}
                      />
                    </div>
                    <div className="grid gap-3">
                      <Label className="text-[10px] font-black uppercase tracking-widest text-primary">Args (comma-separated)</Label>
                      <Input
                        placeholder="e.g. -y, @modelcontextprotocol/server-everything"
                        className="bg-black/20 border-foreground/10 h-11 text-xs font-mono"
                        value={args}
                        onChange={(e) => setArgs(e.target.value)}
                      />
                    </div>
                    <div className="grid gap-3">
                      <Label className="text-[10px] font-black uppercase tracking-widest text-primary">Environment (KEY=VALUE, one per line)</Label>
                      <textarea
                        placeholder={"DEBUG=true\nAPI_KEY=xxx"}
                        className="bg-black/20 border border-foreground/10 rounded-md p-3 text-xs font-mono text-foreground min-h-[80px] resize-y"
                        value={env}
                        onChange={(e) => setEnv(e.target.value)}
                      />
                    </div>
                  </>
                ) : (
                  <>
                    <div className="grid gap-3">
                      <Label className="text-[10px] font-black uppercase tracking-widest text-primary">URL</Label>
                      <Input
                        placeholder="e.g. http://localhost:3001/sse"
                        className="bg-black/20 border-foreground/10 h-11 text-xs font-mono"
                        value={url}
                        onChange={(e) => setUrl(e.target.value)}
                      />
                    </div>
                    {transport === "streamable-http" && (
                      <div className="grid gap-3">
                        <Label className="text-[10px] font-black uppercase tracking-widest text-primary">Headers (Key: Value, one per line)</Label>
                        <textarea
                          placeholder={"Authorization: Bearer xxx"}
                          className="bg-black/20 border border-foreground/10 rounded-md p-3 text-xs font-mono text-foreground min-h-[80px] resize-y"
                          value={headers}
                          onChange={(e) => setHeaders(e.target.value)}
                        />
                      </div>
                    )}
                  </>
                )}
              </div>

              <DialogFooter className="pt-6 border-t border-foreground/10 mt-6">
                <Button
                  onClick={handleFormSubmit}
                  disabled={loading || !name.trim()}
                  className="w-full h-14 bg-primary text-primary-foreground font-black uppercase tracking-[0.2em] hover:opacity-90"
                >
                  {loading ? "Connecting..." : "Add & Connect Server"}
                </Button>
              </DialogFooter>
            </TabsContent>

            {/* ===== JSON Mode ===== */}
            <TabsContent value="json" className="mt-6">
              <div className="grid gap-4">
                <div className="grid gap-3">
                  <Label className="text-[10px] font-black uppercase tracking-widest text-primary">
                    mcp.json 형식으로 입력
                  </Label>
                  <p className="text-[10px] text-foreground/40 font-mono">
                    여러 서버를 한 번에 등록할 수 있습니다. Claude Desktop의 mcp.json 설정을 그대로 붙여넣기 하세요.
                  </p>
                  <textarea
                    placeholder={JSON_PLACEHOLDER}
                    className="bg-black/30 border border-foreground/10 rounded-md p-4 text-xs font-mono text-foreground min-h-[280px] resize-y leading-relaxed focus:outline-none focus:border-primary/50 transition-colors"
                    value={jsonInput}
                    onChange={(e) => {
                      setJsonInput(e.target.value);
                      setJsonError(null);
                    }}
                    spellCheck={false}
                  />
                </div>

                {jsonError && (
                  <div className="p-3 rounded-md bg-red-500/10 border border-red-500/20 text-red-400 text-xs font-mono">
                    {jsonError}
                  </div>
                )}

                <div className="p-4 rounded-md bg-foreground/5 border border-foreground/5 space-y-2">
                  <p className="text-[9px] font-black uppercase tracking-widest text-foreground/30">지원 형식</p>
                  <div className="text-[10px] font-mono text-foreground/50 space-y-1">
                    <p>{'{ "mcpServers": { "name": { ... } } }'} — mcp.json 전체</p>
                    <p>{'{ "name": { "transport": "stdio", ... } }'} — 서버 설정만</p>
                  </div>
                </div>
              </div>

              <DialogFooter className="pt-6 border-t border-foreground/10 mt-6">
                <Button
                  onClick={handleJsonSubmit}
                  disabled={loading || !jsonInput.trim()}
                  className="w-full h-14 bg-primary text-primary-foreground font-black uppercase tracking-[0.2em] hover:opacity-90"
                >
                  <FileJson className="w-4 h-4 mr-2" />
                  {loading ? "Registering..." : "Import & Connect"}
                </Button>
              </DialogFooter>
            </TabsContent>
          </Tabs>
        </div>
      </DialogContent>
    </Dialog>
  );
}
