import { fail, guard, ok, readJson } from "@/lib/api";
import { prisma } from "@/lib/db";
import {
  applyFields,
  extractFields,
  readConfigContent,
  resolveConfigPath,
  writeConfigContent,
  type ExtractedFields,
} from "@/lib/configFile";
import type { AgentKind } from "@/lib/agents/types";
import type { DeployMethod } from "@/lib/deploy";

async function loadAgent(id: string) {
  const a = await prisma.agent.findUnique({ where: { id } });
  if (!a) return null;
  return a;
}

export async function GET(_req: Request, ctx: { params: Promise<{ id: string }> }) {
  const g = await guard(); if (g) return g;
  const { id } = await ctx.params;
  const a = await loadAgent(id);
  if (!a) return fail("not_found", 404);

  const meta = await resolveConfigPath({
    hostId: a.hostId,
    kind: a.kind as AgentKind,
    deployMethod: a.deployMethod as DeployMethod,
    deployRef: a.deployRef,
    configJson: a.configJson,
  });

  if (!meta.exists) {
    return ok({ exists: false, path: meta.path, format: meta.format, tried: meta.tried, user: meta.user, content: "", fields: {} });
  }
  const r = await readConfigContent(a.hostId, meta.path, meta.user);
  if (!r.ok) {
    return ok({ exists: true, path: meta.path, format: meta.format, tried: meta.tried, user: meta.user, content: "", fields: {}, error: r.error });
  }
  const fields = extractFields(r.content, meta.format, a.kind as AgentKind);
  return ok({ exists: true, path: meta.path, format: meta.format, tried: meta.tried, user: meta.user, content: r.content, fields });
}

export async function PUT(req: Request, ctx: { params: Promise<{ id: string }> }) {
  const g = await guard(); if (g) return g;
  const { id } = await ctx.params;
  const a = await loadAgent(id);
  if (!a) return fail("not_found", 404);

  const body = await readJson<{ content?: string; fields?: ExtractedFields; mode?: "raw" | "fields" }>(req);
  const mode = body.mode || (body.content !== undefined ? "raw" : "fields");

  const meta = await resolveConfigPath({
    hostId: a.hostId,
    kind: a.kind as AgentKind,
    deployMethod: a.deployMethod as DeployMethod,
    deployRef: a.deployRef,
    configJson: a.configJson,
  });

  let newContent = "";
  const warnings: string[] = [];

  if (mode === "raw") {
    if (typeof body.content !== "string") return fail("missing_content");
    newContent = body.content;
  } else {
    const cur = meta.exists ? await readConfigContent(a.hostId, meta.path, meta.user) : { content: "", ok: true };
    const baseContent = cur.ok ? cur.content : "";
    const applied = applyFields(baseContent || (meta.format === "json" ? "{}" : ""), meta.format, a.kind as AgentKind, body.fields || {});
    newContent = applied.content;
    warnings.push(...applied.warnings);
  }

  const w = await writeConfigContent(a.hostId, meta.path, newContent, meta.user);
  if (!w.ok) return fail(`write_failed: ${w.error}`);

  // Log event để có lịch sử
  await prisma.agentEvent.create({
    data: {
      agentId: a.id,
      kind: "config-edit",
      status: "ok",
      message: `Sửa ${meta.path}`,
      log: warnings.length ? warnings.join("\n") : "ok",
      durationMs: 0,
    },
  });

  return ok({ ok: true, path: meta.path, format: meta.format, warnings });
}
