import { describe, expect, it } from "vitest";
import { createConfig } from "../../config.js";
import { MiddlewareManager } from "../../middlewares/middleware.js";
import { getMainRouter } from "../../routers/index.js";
import { createSignedAdminToken } from "../helpers/adminTokenTestUtils.js";

const ADMIN_TOKEN_SIGNING_SECRET = "admin-test-secret";
const ADMIN_TOKEN_AUDIENCE = "xtablo-admin";

describe("Admin Tables Router", () => {
  process.env.ADMIN_TOKEN_SIGNING_SECRET = ADMIN_TOKEN_SIGNING_SECRET;
  process.env.ADMIN_TOKEN_AUDIENCE = ADMIN_TOKEN_AUDIENCE;
  process.env.ADMIN_APP_URL = "http://localhost:5176";

  const config = createConfig();
  MiddlewareManager.initialize(config);
  const app = getMainRouter(config);

  const sessionToken = createSignedAdminToken(
    {
      aud: ADMIN_TOKEN_AUDIENCE,
      email: "ops@xtablo.com",
      exp: Math.floor(Date.now() / 1000) + 900,
      role: "operator",
      sub: "operator-1",
      type: "admin_session",
    },
    ADMIN_TOKEN_SIGNING_SECRET
  );

  it("lists only approved admin tables", async () => {
    const res = await app.request("/admin/tables", {
      headers: {
        Authorization: `Bearer ${sessionToken}`,
      },
    });

    expect(res.status).toBe(200);
    await expect(res.json()).resolves.toMatchObject({
      tables: expect.arrayContaining([
        expect.objectContaining({
          id: "profiles",
          label: "Users",
        }),
      ]),
    });
  });

  it("returns metadata for an approved table", async () => {
    const res = await app.request("/admin/tables/profiles/meta", {
      headers: {
        Authorization: `Bearer ${sessionToken}`,
      },
    });

    expect(res.status).toBe(200);
    await expect(res.json()).resolves.toMatchObject({
      id: "profiles",
      label: "Users",
      editableFields: ["first_name", "last_name"],
      primaryKey: "id",
      columns: expect.arrayContaining([
        expect.objectContaining({
          id: "email",
          label: "Email",
        }),
      ]),
    });
  });

  it("returns rows for an approved table", async () => {
    const res = await app.request("/admin/tables/profiles/rows", {
      headers: {
        Authorization: `Bearer ${sessionToken}`,
      },
    });

    expect(res.status).toBe(200);
    await expect(res.json()).resolves.toMatchObject({
      rows: expect.arrayContaining([
        expect.objectContaining({
          email: "test_owner@example.com",
        }),
      ]),
    });
  });

  it("rejects tables that are not in the registry", async () => {
    const res = await app.request("/admin/tables/secrets/meta", {
      headers: {
        Authorization: `Bearer ${sessionToken}`,
      },
    });

    expect(res.status).toBe(404);
    await expect(res.json()).resolves.toMatchObject({
      error: "Admin table 'secrets' is not registered",
    });
  });
});
