import { fail, guard, ok, readJson } from "@/lib/api";
import { prisma } from "@/lib/db";
import { AGENT_KINDS, type AgentKind } from "@/lib/agents";

export async function GET() {
  const g = await guard(); if (g) return g;
  const agents = await prisma.agent.findMany({
    orderBy: { createdAt: "desc" },
    include: { host: { select: { id: true, name: true, host: true } } },
  });
  return ok({ agents });
}

type Body = {
  name?: string;
  kind?: string;
  hostId?: string;
  installPath?: string;
  configJson?: string;
  notes?: string;
  autoStart?: boolean;
  // Khai báo agent có sẵn:
  declared?: boolean;
  deployMethod?: string;
  deployRef?: string;
};

export async function POST(req: Request) {
  const g = await guard(); if (g) return g;
  const b = await readJson<Body>(req);
  if (!b.name || !b.kind || !b.hostId) return fail("missing_fields");
  if (!AGENT_KINDS.includes(b.kind as AgentKind)) return fail("invalid_kind");

  // Tên agent dùng làm name systemd unit + thư mục → ràng buộc ký tự an toàn.
  if (!/^[a-zA-Z0-9_-]{2,40}$/.test(b.name)) return fail("invalid_name");

  const declared = !!b.declared;
  const deployMethod = (b.deployMethod ?? "systemd") as "systemd" | "docker" | "pm2" | "manual";
  if (!["systemd", "docker", "pm2", "manual"].includes(deployMethod)) return fail("invalid_deploy_method");
  let deployRef = (b.deployRef ?? "").trim();
  // Với agent có sẵn (declared), các method ngoài systemd bắt buộc có ref.
  if (declared && deployMethod !== "systemd" && !deployRef) {
    return fail("deploy_ref_required");
  }
  // Với declared + systemd, mặc định lấy đúng tên user khai (fallback agent-<name>.service).
  if (deployMethod === "systemd" && !deployRef) deployRef = "";

  const a = await prisma.agent.create({
    data: {
      name: b.name,
      kind: b.kind,
      hostId: b.hostId,
      installPath: b.installPath || "/opt",
      configJson: b.configJson || "{}",
      notes: b.notes,
      autoStart: !!b.autoStart,
      status: declared ? "declared" : "unknown",
      declared,
      deployMethod,
      deployRef,
    },
  });
  return ok({ id: a.id }, 201);
}
