import type { Hono } from "hono";
import type { Env } from "../types/env";
import type { CfAccountRow } from "../types/account";
import { jsonError } from "../lib/http";
import { requirePanelForManagement } from "../lib/auth";

/** Cloudflare 账号 CRUD（D1） */
export function registerAccountRoutes(app: Hono<{ Bindings: Env }>): void {
  app.get("/api/accounts", async (c) => {
    const denied = requirePanelForManagement(c);
    if (denied) return denied;
    const res = await c.env.DB.prepare(
      "SELECT id, name, token, created_at FROM cf_accounts ORDER BY created_at ASC",
    ).all<CfAccountRow>();
    return c.json({ accounts: res.results ?? [] });
  });

  app.post("/api/accounts", async (c) => {
    const denied = requirePanelForManagement(c);
    if (denied) return denied;
    let body: { name?: string; token?: string };
    try {
      body = await c.req.json();
    } catch {
      return jsonError(400, "Invalid JSON body");
    }
    const token = String(body.token ?? "").trim();
    if (!token) return jsonError(400, "token is required");
    const name = String(body.name ?? "").trim() || "账号";
    const id = crypto.randomUUID();
    await c.env.DB.prepare(
      "INSERT INTO cf_accounts (id, name, token) VALUES (?1, ?2, ?3)",
    )
      .bind(id, name, token)
      .run();
    const row = await c.env.DB.prepare(
      "SELECT id, name, token, created_at FROM cf_accounts WHERE id = ?1",
    )
      .bind(id)
      .first<CfAccountRow>();
    return c.json({ account: row }, 201);
  });

  app.patch("/api/accounts/:id", async (c) => {
    const denied = requirePanelForManagement(c);
    if (denied) return denied;
    const id = c.req.param("id");
    const existing = await c.env.DB.prepare(
      "SELECT id, name, token FROM cf_accounts WHERE id = ?1",
    )
      .bind(id)
      .first<{ id: string; name: string; token: string }>();
    if (!existing) return jsonError(404, "Account not found");
    let body: { name?: string; token?: string };
    try {
      body = await c.req.json();
    } catch {
      return jsonError(400, "Invalid JSON body");
    }
    const name =
      body.name !== undefined ? String(body.name).trim() || "账号" : existing.name;
    const token =
      body.token !== undefined ? String(body.token).trim() : existing.token;
    if (!token) return jsonError(400, "token cannot be empty");
    await c.env.DB.prepare(
      "UPDATE cf_accounts SET name = ?1, token = ?2 WHERE id = ?3",
    )
      .bind(name, token, id)
      .run();
    const row = await c.env.DB.prepare(
      "SELECT id, name, token, created_at FROM cf_accounts WHERE id = ?1",
    )
      .bind(id)
      .first<CfAccountRow>();
    return c.json({ account: row });
  });

  app.delete("/api/accounts/:id", async (c) => {
    const denied = requirePanelForManagement(c);
    if (denied) return denied;
    const id = c.req.param("id");
    const r = await c.env.DB.prepare("DELETE FROM cf_accounts WHERE id = ?1")
      .bind(id)
      .run();
    if (r.meta.changes === 0) return jsonError(404, "Account not found");
    return c.json({ ok: true });
  });
}
