import "./setup-env.js";
import { describe, expect, it, beforeAll, afterAll } from "vitest";
import { eq, inArray } from "drizzle-orm";
import { buildServer } from "../src/server.js";
import { loadConfig } from "../src/config.js";
import { createDatabase, closeDatabase, schema } from "@app/database";

describe("inventory trust read-time computation", () => {
  const testDb = createDatabase(process.env.TEST_DATABASE_URL!);
  const config = loadConfig();
  let app: Awaited<ReturnType<typeof buildServer>>;
  let accessToken: string;
  let householdId: string;
  let locationId: string;
  const userEmail = "trust-read@example.invalid";

  async function cleanup() {
    const existing = await testDb.db
      .select({ id: schema.users.id })
      .from(schema.users)
      .where(inArray(schema.users.email, [userEmail]));
    for (const u of existing) {
      await testDb.db.delete(schema.inventoryTransactions).where(eq(schema.inventoryTransactions.actorUserId, u.id));
      const owned = await testDb.db
        .select({ id: schema.households.id })
        .from(schema.households)
        .innerJoin(schema.householdMembers, eq(schema.householdMembers.householdId, schema.households.id))
        .where(eq(schema.householdMembers.userId, u.id));
      for (const h of owned) {
        await testDb.db.delete(schema.inventoryItems).where(eq(schema.inventoryItems.householdId, h.id));
        await testDb.db.delete(schema.storageLocations).where(eq(schema.storageLocations.householdId, h.id));
        await testDb.db.delete(schema.households).where(eq(schema.households.id, h.id));
      }
      await testDb.db.delete(schema.householdMembers).where(eq(schema.householdMembers.userId, u.id));
      await testDb.db.delete(schema.userPreferences).where(eq(schema.userPreferences.userId, u.id));
      await testDb.db.delete(schema.users).where(eq(schema.users.id, u.id));
    }
  }

  beforeAll(async () => {
    await cleanup();
    app = await buildServer(config);
    await app.ready();

    const res = await app.inject({
      method: "POST",
      url: "/v1/auth/register",
      payload: { email: userEmail, password: "Password123!", displayName: "Trust" },
    });
    const body = JSON.parse(res.body) as { accessToken: string };
    accessToken = body.accessToken;

    const quick = await app.inject({
      method: "POST",
      url: "/v1/onboarding/quick-start",
      headers: { authorization: `Bearer ${accessToken}` },
      payload: { goals: ["cook_more"], precisionMode: "simple" },
    });
    const quickBody = JSON.parse(quick.body) as { householdId: string };
    householdId = quickBody.householdId;

    const [location] = await testDb.db
      .select()
      .from(schema.storageLocations)
      .where(eq(schema.storageLocations.householdId, householdId))
      .limit(1);
    locationId = location!.id;
  });

  afterAll(async () => {
    await cleanup();
    await closeDatabase();
    await app.close();
  });

  it("reports decaying/stale for items with old lastVerifiedAt without a write", async () => {
    const fortyDaysAgo = new Date(Date.now() - 40 * 86_400_000);

    const [item] = await testDb.db
      .insert(schema.inventoryItems)
      .values({
        householdId,
        displayName: "Gammal mjölk",
        quantity: 1,
        unit: "LITER",
        storageLocationId: locationId,
        source: "manual_search",
        confidence: 0.6,
        verifiedByUser: true,
        lastVerifiedAt: fortyDaysAgo,
        updatedAt: fortyDaysAgo,
      })
      .returning();

    const res = await app.inject({
      method: "GET",
      url: "/v1/inventory",
      headers: { authorization: `Bearer ${accessToken}` },
    });
    expect(res.statusCode).toBe(200);

    const body = JSON.parse(res.body) as { items: Array<{ id: string; trustState: string; trustScore: number }> };
    const found = body.items.find((i) => i.id === item!.id);
    expect(found).toBeTruthy();
    expect(["decaying", "stale"]).toContain(found!.trustState);
    expect(found!.trustScore).toBeLessThan(60);
  });
});
