// Pet CRUD test
import { describe, it, before, after } from "node:test";
import assert from "node:assert/strict";
import { buildApp } from "../index.js";
import type { FastifyInstance } from "fastify";

let app: FastifyInstance;
let token: string;
let createdId: string;
let payload: Record<string, unknown>;

before(async () => {
  process.env.JWT_SECRET = "test-secret";
  process.env.DATABASE_URL = ":memory:";
  app = await buildApp();
  await app.ready();

  // Register and login to get a token
  const regRes = await app.inject({
    method: "POST",
    url: "/api/auth/register",
    payload: { username: `test_${Date.now()}`, password: "password123" },
  });
  token = regRes.json().token;

  // Resolve user FK references with the registered user's real ID
  payload = {
          "userId": regRes.json().user.id,
          "name": "sample-name",
          "species": "sample-species",
          "breed": "sample-breed",
          "birthDate": "sample-birthdate",
          "weightKg": 1,
          "avatarUrl": "sample-avatarurl"
      };
});

after(async () => {
  await app.close();
});

describe("GET /api/pets", () => {
  it("returns empty list", async () => {
    const res = await app.inject({
      method: "GET",
      url: "/api/pets",
      headers: { authorization: `Bearer ${token}` },
    });
    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.ok(Array.isArray(body.data));
  });
});

describe("POST /api/pets", () => {
  it("creates a pet", async () => {
    const res = await app.inject({
      method: "POST",
      url: "/api/pets",
      headers: { authorization: `Bearer ${token}` },
      payload,
    });
    assert.equal(res.statusCode, 201);
    const body = res.json();
    assert.ok(body.data.id);
    createdId = body.data.id;
  });
});

describe("GET /api/pets/:id", () => {
  it("returns the created pet", async () => {
    const res = await app.inject({
      method: "GET",
      url: `/api/pets/${createdId}`,
      headers: { authorization: `Bearer ${token}` },
    });
    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.equal(body.data.id, createdId);
  });

  it("returns 404 for nonexistent id", async () => {
    const res = await app.inject({
      method: "GET",
      url: `/api/pets/nonexistent`,
      headers: { authorization: `Bearer ${token}` },
    });
    assert.equal(res.statusCode, 404);
  });
});

describe("PUT /api/pets/:id", () => {
  it("updates the pet", async () => {
    const res = await app.inject({
      method: "PUT",
      url: `/api/pets/${createdId}`,
      headers: { authorization: `Bearer ${token}` },
      payload,
    });
    assert.equal(res.statusCode, 200);
  });
});

describe("DELETE /api/pets/:id", () => {
  it("deletes the pet", async () => {
    const res = await app.inject({
      method: "DELETE",
      url: `/api/pets/${createdId}`,
      headers: { authorization: `Bearer ${token}` },
    });
    assert.equal(res.statusCode, 204);
  });

  it("returns 404 after delete", async () => {
    const res = await app.inject({
      method: "GET",
      url: `/api/pets/${createdId}`,
      headers: { authorization: `Bearer ${token}` },
    });
    assert.equal(res.statusCode, 404);
  });
});
