import { env } from "cloudflare:test";
import { beforeEach, describe, expect, it } from "vitest";
import app from "../src/app";
import { seedLicenseAndBucket, TEST_LICENSE } from "./helpers";

function post(body: unknown) {
  return app.request(
    "/v1/sites/activate",
    {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(body),
    },
    env,
  );
}

describe("POST /v1/sites/activate", () => {
  beforeEach(seedLicenseAndBucket);

  it("creates a site and returns a token + plan", async () => {
    const res = await post({ license_key: TEST_LICENSE, site_url: "https://a.tld" });
    expect(res.status).toBe(201);
    const body = (await res.json()) as {
      site_id: string;
      site_token: string;
      plan: { storage_bytes_limit: number; retention_days: number };
    };
    expect(body.site_id.length).toBeGreaterThan(10);
    expect(body.site_token.split(".").length).toBe(3);
    expect(body.plan).toEqual({ storage_bytes_limit: 1_000_000, retention_days: 30 });
    const bucket = await env.DB.prepare("SELECT site_count FROM buckets WHERE id = 1")
      .first<{ site_count: number }>();
    expect(bucket?.site_count).toBe(1);
  });

  it("re-activation keeps site_id and rotates token_version", async () => {
    const first = (await (await post({ license_key: TEST_LICENSE, site_url: "https://a.tld" })).json()) as { site_id: string };
    const res = await post({ license_key: TEST_LICENSE, site_url: "https://a.tld" });
    expect(res.status).toBe(201);
    const second = (await res.json()) as { site_id: string };
    expect(second.site_id).toBe(first.site_id);
    const row = await env.DB.prepare("SELECT token_version FROM sites WHERE id = ?")
      .bind(first.site_id)
      .first<{ token_version: number }>();
    expect(row?.token_version).toBe(2);
  });

  it("rejects an unknown license with 403", async () => {
    const res = await post({ license_key: "WPB-NOPE", site_url: "https://a.tld" });
    expect(res.status).toBe(403);
    const body = (await res.json()) as { error: { code: string } };
    expect(body.error.code).toBe("invalid_license");
  });

  it("rejects when max_sites is reached", async () => {
    await post({ license_key: TEST_LICENSE, site_url: "https://a1.tld" });
    await post({ license_key: TEST_LICENSE, site_url: "https://a2.tld" });
    await post({ license_key: TEST_LICENSE, site_url: "https://a3.tld" });
    const res = await post({ license_key: TEST_LICENSE, site_url: "https://a4.tld" });
    expect(res.status).toBe(403);
    const body = (await res.json()) as { error: { code: string } };
    expect(body.error.code).toBe("site_limit_reached");
  });

  it("rejects malformed body and bad URLs with 400", async () => {
    expect((await post({ license_key: TEST_LICENSE })).status).toBe(400);
    expect(
      (await post({ license_key: TEST_LICENSE, site_url: "not-a-url" })).status,
    ).toBe(400);
  });
});
