import { afterEach, describe, expect, it, vi } from "vitest";
import { createUnpaidV3Challenge } from "../../../repos/theloopbreaker-site/app/api/v3/x402/_lib/challenge";
import { V3_ROUTES, assertV3RouteRegistry } from "../../../repos/theloopbreaker-site/app/api/v3/x402/_lib/registry";
import { isAllowedV3ReleasePath, isV3X402ReleaseEnabled, V3_X402_RELEASE_ENV, V3_X402_RELEASE_VALUE } from "../../../repos/theloopbreaker-site/app/api/v3/x402/_lib/release";
import { assertV3DiscoveryDocument, createV3DiscoveryDocument, GET as getDiscovery } from "../../../repos/theloopbreaker-site/app/api/v3/x402/discovery/route";
import { GET as getChallengeStatus } from "../../../repos/theloopbreaker-site/app/api/v3/x402/challenge-status/route";
import { GET as getStatus } from "../../../repos/theloopbreaker-site/app/api/v3/protocol/status/route";
import { GET as getSolvency } from "../../../repos/theloopbreaker-site/app/api/v3/protocol/solvency/route";
import { GET as getSolanaHealth } from "../../../repos/theloopbreaker-site/app/api/v3/solana/health/route";
import { GET as getMandate } from "../../../repos/theloopbreaker-site/app/api/v3/mandate/[mandateHash]/route";
import { POST as createPartnershipBond } from "../../../repos/theloopbreaker-site/app/api/v3/x402/actions/create-partnership-bond/route";
import { createReceiptStatusResponse } from "../../../repos/theloopbreaker-site/app/api/v3/x402/_lib/receipt-status";
import bazaar from "../../generated/coinbase-bazaar-v2.json" assert { type: "json" };
import registry from "../../generated/route-registry.json" assert { type: "json" };

const originalFlag = process.env[V3_X402_RELEASE_ENV];
afterEach(() => {
  if (originalFlag === undefined) delete process.env[V3_X402_RELEASE_ENV];
  else process.env[V3_X402_RELEASE_ENV] = originalFlag;
  vi.restoreAllMocks();
});

describe("additive V3 website x402 surface", () => {
  it("requires the exact release value and permits only V3 materialized paths", () => {
    expect(isV3X402ReleaseEnabled({})).toBe(false);
    expect(isV3X402ReleaseEnabled({ [V3_X402_RELEASE_ENV]: "true" })).toBe(false);
    expect(isV3X402ReleaseEnabled({ [V3_X402_RELEASE_ENV]: V3_X402_RELEASE_VALUE })).toBe(true);
    for (const path of ["/api/v3/protocol/status", "/api/v3/x402/challenge-status", "/api/v3/solana/health", "/api/v3/x402/receipts/v3r_89abcdef0123456789abcdef01234567"]) {
      expect(isAllowedV3ReleasePath(path), path).toBe(true);
    }
    expect(isAllowedV3ReleasePath("/api/v3/x402/receipts/request-1")).toBe(false);
    expect(isAllowedV3ReleasePath("/api/x402/actions/create-partnership-bond")).toBe(false);
    expect(isAllowedV3ReleasePath("/api/v3/x402/actions/unknown")).toBe(false);
  });

  it("keeps the additive V3 registry free and out of Bazaar payment candidate metadata", () => {
    assertV3RouteRegistry(V3_ROUTES);
    expect(() => assertV3RouteRegistry(V3_ROUTES.slice(0, 19))).toThrow("exactly 20 routes");
    const generated = registry.routes.filter((route) => route.version === "v3");
    expect(generated.map((route) => `${route.method} ${route.path}`)).toEqual(V3_ROUTES.map((route) => `${route.method} ${route.path}`));
    expect(generated).toHaveLength(20);
    for (const route of generated) {
      expect(route.free).toBe(true);
      expect(route.contractStatus).toBe("read-only");
      expect(route.bazaarEligibility).toBe("not-priced");
      expect(route.price).toBeUndefined();
      expect(route.accepts).toBeUndefined();
    }
    expect(bazaar.resources.filter((resource) => resource.protocolVersion === "v3")).toHaveLength(0);
    expect(bazaar.publicationState).toBe("metadata-candidates-not-live-validated");
  });

  it("does not issue a payment challenge or parse an attempted payment", async () => {
    const response = createUnpaidV3Challenge(
      new Request("https://theloopbreaker.com/api/v3/x402/actions/create-partnership-bond", {
        method: "POST", headers: { "PAYMENT-SIGNATURE": "must-not-be-parsed" }, body: "must-not-be-read",
      }),
      V3_ROUTES.find((route) => route.id === 'retired-partnership-write')!,
    );
    expect(response.status).toBe(503);
    expect(response.headers.has("payment-required")).toBe(false);
    expect(response.headers.has("payment-response")).toBe(false);
    expect(await response.json()).toMatchObject({
      code: "v3_payment_challenge_unavailable",
      evidence: { requestInspected: false, paymentHeaderObserved: false, paymentParsed: false, paymentProcessed: false, requestBound: false, receiptCreated: false, settlementVerified: false },
      safety: { walletConnectionRequested: false, signatureRequested: false, paymentSubmitted: false, v2FallbackUsed: false },
    });
  });

  it("serves safe static discovery/status surfaces only under the exact release flag", async () => {
    delete process.env[V3_X402_RELEASE_ENV];
    expect(getDiscovery().status).toBe(503);
    process.env[V3_X402_RELEASE_ENV] = V3_X402_RELEASE_VALUE;
    const discovery = getDiscovery();
    expect(discovery.status).toBe(200);
    const document = await discovery.json();
    expect(() => assertV3DiscoveryDocument(document)).not.toThrow();
    expect(document).toMatchObject({
      settlement: { enabled: false, evidenceVerified: false, realV3AddressVerified: false },
      safety: { v2Fallback: false, missionSensitiveDecisionInputs: "retired-or-fail-closed" },
    });
    expect(document.endpoints).toHaveLength(20);
    expect(createV3DiscoveryDocument(new Date(0)).generatedAt).toBe("1970-01-01T00:00:00.000Z");

    for (const response of [getStatus(), getSolvency()]) {
      expect(response.status).toBe(503);
      const body = await response.json();
      expect(JSON.stringify(body)).not.toMatch(/0x[a-fA-F0-9]{40}/);
    }
    for (const response of [getChallengeStatus(), getSolanaHealth()]) {
      expect(response.status).toBe(200);
      const body = await response.json();
      expect(JSON.stringify(body)).not.toMatch(/0x[a-fA-F0-9]{40}/);
    }
    expect(await (await getChallengeStatus()).json()).toMatchObject({ challengeAvailable: false, paymentAccepted: false, settlementEnabled: false, bazaar: { listingReceiptIds: [], indexingVerified: false } });
    expect(await (await getSolanaHealth()).json()).toMatchObject({ operational: false, rpcContacted: false, indexerContacted: false, paymentSettlementEnabled: false });
  });

  it("keeps V3 read/write and receipt surfaces fail-closed without evidence", async () => {
    process.env[V3_X402_RELEASE_ENV] = V3_X402_RELEASE_VALUE;
    const hash = `0x${"11".repeat(32)}`;
    expect((await getMandate(new Request(`https://theloopbreaker.com/api/v3/mandate/${hash}`), { params: { mandateHash: hash } })).status).toBe(503);
    expect(await (await createPartnershipBond(new Request("https://theloopbreaker.com/api/v3/x402/actions/create-partnership-bond", { method: "POST" }))).json()).toMatchObject({ schema: "vaultfire.v3.x402.retirement.v1", executable: false, bodyParsed: false });
    expect((await createReceiptStatusResponse("v3r_789abcdef0123456789abcdef0123456", {})).status).toBe(503);
    expect((await getMandate(new Request("https://theloopbreaker.com/api/v3/mandate/not-a-hash"), { params: { mandateHash: "not-a-hash" } })).status).toBe(400);
  });
});
