"use client";

import { useState } from "react";
import { toast } from "sonner";
import { api, type Connection } from "@/components/api";
import { keyValueLinesFromJson, parseKeyValueLines } from "@/components/kv";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";

interface ConnectionDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** 传入则为编辑，否则为新建 */
  initial?: Connection | null;
  onSaved: () => void;
}

const EMPTY = {
  name: "",
  type: "mysql",
  host: "127.0.0.1",
  port: "3306",
  user: "root",
  password: "",
  database: "",
};

export function ConnectionDialog({
  open,
  onOpenChange,
  initial,
  onSaved,
}: ConnectionDialogProps) {
  const [form, setForm] = useState(() =>
    initial
      ? {
          name: initial.name,
          type: initial.type,
          host: initial.host,
          port: String(initial.port),
          user: initial.user,
          password: initial.password,
          database: initial.database,
        }
      : EMPTY
  );
  const [saving, setSaving] = useState(false);
  const [paramsText, setParamsText] = useState(() =>
    initial ? keyValueLinesFromJson(initial.params) : ""
  );

  const set = (k: keyof typeof EMPTY) => (e: React.ChangeEvent<HTMLInputElement>) =>
    setForm((f) => ({ ...f, [k]: e.target.value }));

  async function submit() {
    if (!form.name.trim() || !form.host.trim() || !form.database.trim()) {
      toast.error("请填写名称、host 和 database");
      return;
    }
    const port = Number(form.port) || 3306;
    setSaving(true);
    try {
      const body = JSON.stringify({
        name: form.name.trim(),
        type: form.type,
        host: form.host.trim(),
        port,
        user: form.user.trim(),
        password: form.password,
        database: form.database.trim(),
        params: parseKeyValueLines(paramsText),
      });
      if (initial) {
        await api(`/api/connections/${initial.id}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body,
        });
        toast.success("连接已更新");
      } else {
        await api("/api/connections", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body,
        });
        toast.success("连接已创建");
      }
      onOpenChange(false);
      onSaved();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "保存失败");
    } finally {
      setSaving(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{initial ? "编辑连接" : "新建连接"}</DialogTitle>
        </DialogHeader>
        <div className="grid gap-3">
          <div className="grid gap-1.5">
            <Label htmlFor="conn-name">名称</Label>
            <Input
              id="conn-name"
              value={form.name}
              onChange={set("name")}
              placeholder="例如：测试环境 MySQL"
            />
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div className="grid gap-1.5">
              <Label>类型</Label>
              <Select
                value={form.type}
                onValueChange={(v) => setForm((f) => ({ ...f, type: String(v) }))}
              >
                <SelectTrigger className="w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="mysql">mysql</SelectItem>
                  <SelectItem value="mariadb">mariadb</SelectItem>
                  <SelectItem value="tidb">tidb</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="grid gap-1.5">
              <Label htmlFor="conn-port">端口</Label>
              <Input
                id="conn-port"
                type="number"
                value={form.port}
                onChange={set("port")}
              />
            </div>
          </div>
          <div className="grid gap-1.5">
            <Label htmlFor="conn-host">Host</Label>
            <Input id="conn-host" value={form.host} onChange={set("host")} />
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div className="grid gap-1.5">
              <Label htmlFor="conn-user">用户名</Label>
              <Input id="conn-user" value={form.user} onChange={set("user")} />
            </div>
            <div className="grid gap-1.5">
              <Label htmlFor="conn-password">密码</Label>
              <Input
                id="conn-password"
                type="password"
                value={form.password}
                onChange={set("password")}
              />
            </div>
          </div>
          <div className="grid gap-1.5">
            <Label htmlFor="conn-db">数据库</Label>
            <Input
              id="conn-db"
              value={form.database}
              onChange={set("database")}
            />
          </div>
          <div className="grid gap-1.5">
            <Label htmlFor="conn-params">连接参数</Label>
            <Textarea
              id="conn-params"
              className="font-mono text-xs"
              rows={3}
              value={paramsText}
              onChange={(e) => setParamsText(e.target.value)}
              placeholder={"tidb_skip_isolation_level_check=1"}
            />
            <p className="text-xs text-muted-foreground">
              每行一个 key=value，作为 URL 查询参数传递，sling / atlas 均生效；TiDB
              目标库建议设置 tidb_skip_isolation_level_check=1。
            </p>
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={saving}>
            取消
          </Button>
          <Button onClick={submit} disabled={saving}>
            {saving ? "保存中…" : "保存"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
