/**
 * GDPR helpers for product analytics – integration tests.
 * Assumes DATABASE_URL points to a writable database.
 */
import { describe, expect, it, beforeAll, afterAll } from "vitest";
import { eq } from "drizzle-orm";
import { createDatabase, closeDatabase, schema, isAnalyticsOptedIn, deleteUserAnalyticsEvents } from "@app/database";

const TEST_USER_EMAIL = "analytics-gdpr-test@example.invalid";

describe("analytics GDPR helpers", () => {
  const { db, pool } = createDatabase();
  let userId: string;

  beforeAll(async () => {
    // Clean up any stale test user.
    await db.delete(schema.users).where(eq(schema.users.email, TEST_USER_EMAIL));
    const [user] = await db
      .insert(schema.users)
      .values({
        email: TEST_USER_EMAIL,
        displayName: "Analytics Test",
        locale: "sv-SE",
      })
      .returning({ id: schema.users.id });
    userId = user!.id;
  });

  afterAll(async () => {
    await db.delete(schema.userConsents).where(eq(schema.userConsents.userId, userId));
    await db.delete(schema.users).where(eq(schema.users.id, userId));
    await closeDatabase();
  });

  it("missing consent row → opted in (legitimate interest, opt-out)", async () => {
    await db.delete(schema.userConsents).where(eq(schema.userConsents.userId, userId));
    expect(await isAnalyticsOptedIn(db, userId)).toBe(true);
  });

  it("explicit granted → opted in", async () => {
    await db
      .insert(schema.userConsents)
      .values({
        userId,
        kind: "product_analytics",
        status: "granted",
        grantedAt: new Date(),
        updatedAt: new Date(),
      })
      .onConflictDoUpdate({
        target: [schema.userConsents.userId, schema.userConsents.kind],
        set: { status: "granted", revokedAt: null, updatedAt: new Date() },
      });
    expect(await isAnalyticsOptedIn(db, userId)).toBe(true);
  });

  it("explicit revoked → opted out", async () => {
    const now = new Date();
    await db
      .insert(schema.userConsents)
      .values({
        userId,
        kind: "product_analytics",
        status: "revoked",
        revokedAt: now,
        updatedAt: now,
      })
      .onConflictDoUpdate({
        target: [schema.userConsents.userId, schema.userConsents.kind],
        set: { status: "revoked", revokedAt: now, updatedAt: now },
      });
    expect(await isAnalyticsOptedIn(db, userId)).toBe(false);
  });

  it("deleteUserAnalyticsEvents removes only the target user's events", async () => {
    // Insert a dummy event for the test user and another user.
    const [otherUser] = await db
      .insert(schema.users)
      .values({ email: "other-analytics-test@example.invalid", displayName: "Other", locale: "sv-SE" })
      .returning({ id: schema.users.id });

    await db.insert(schema.productAnalyticsEvents).values({
      userId,
      eventName: "app_first_open",
      anonymousId: "anon-test",
    });
    await db.insert(schema.productAnalyticsEvents).values({
      userId: otherUser!.id,
      eventName: "app_first_open",
      anonymousId: "anon-other",
    });

    const deleted = await deleteUserAnalyticsEvents(db, userId);
    expect(deleted).toBe(1);

    const remaining = await db
      .select({ id: schema.productAnalyticsEvents.id })
      .from(schema.productAnalyticsEvents)
      .where(eq(schema.productAnalyticsEvents.userId, otherUser!.id));
    expect(remaining).toHaveLength(1);

    await db.delete(schema.productAnalyticsEvents).where(eq(schema.productAnalyticsEvents.userId, otherUser!.id));
    await db.delete(schema.users).where(eq(schema.users.id, otherUser!.id));
  });
});
