// Integration — DB_TESTS=1, *_test uniquement. Valide le partitionnement
// mensuel des snapshots GSC : upsert ON CONFLICT idempotent à travers les
// partitions, routage par mois, cascade delete depuis sites, BRIN présent.
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";

mock.module("server-only", () => ({}));

const RUN = process.env.DB_TESTS === "1";
const NOW = new Date();
const ORG = "gscp-org";
const OWNER = "gscp-owner";
const SITE = "gscp-site";

describe.skipIf(!RUN)("gsc snapshots partitioning (postgres)", () => {
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let db: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let authSchema: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let domain: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let sqlTag: any;

  async function cleanup() {
    const { inArray } = await import("drizzle-orm");
    await db
      .delete(authSchema.organization)
      .where(inArray(authSchema.organization.id, [ORG]));
    await db
      .delete(authSchema.user)
      .where(inArray(authSchema.user.id, [OWNER]));
  }

  beforeEach(async () => {
    ({ db } = await import("@/lib/db/client"));
    authSchema = await import("@/lib/db/auth-schema");
    domain = await import("@/lib/db/domain-schema");
    ({ sql: sqlTag } = await import("drizzle-orm"));
    const { assertTestDb } = await import("@/lib/db/assert-test-db");
    await assertTestDb();
    await cleanup();
    await db.insert(authSchema.user).values({
      id: OWNER,
      name: OWNER,
      email: `${OWNER}@test.dev`,
      emailVerified: true,
      createdAt: NOW,
      updatedAt: NOW,
    });
    await db
      .insert(authSchema.organization)
      .values({ id: ORG, name: ORG, slug: ORG, createdAt: NOW });
    await db.insert(domain.sites).values({
      id: SITE,
      orgId: ORG,
      ownerUserId: OWNER,
      name: "GSC part test",
      primaryLanguage: "fr",
      createdAt: NOW,
    });
  });

  afterAll(async () => {
    if (!RUN) return;
    await cleanup();
  });

  test("la table est bien partitionnée RANGE(date) avec BRIN", async () => {
    const [part] = await db.execute(
      sqlTag`select partstrat from pg_partitioned_table pt
             join pg_class c on c.oid = pt.partrelid
             where c.relname = 'gsc_page_snapshots'`,
    );
    expect(part?.partstrat).toBe("r");
    const idx = await db.execute(
      sqlTag`select indexname from pg_indexes
             where tablename = 'gsc_page_snapshots' and indexdef ilike '%brin%'`,
    );
    expect(idx.length).toBeGreaterThan(0);
  });

  test("upsert ON CONFLICT idempotent, lignes routées vers la partition du mois", async () => {
    const row = {
      siteId: SITE,
      date: "2026-07-15",
      page: "/a",
      clicks: 1,
      impressions: 10,
      ctr: 0.1,
      position: 3.2,
    };
    await db.insert(domain.gscPageSnapshots).values(row);
    await db
      .insert(domain.gscPageSnapshots)
      .values({ ...row, clicks: 5 })
      .onConflictDoUpdate({
        target: [
          domain.gscPageSnapshots.siteId,
          domain.gscPageSnapshots.date,
          domain.gscPageSnapshots.page,
        ],
        set: { clicks: 5 },
      });
    const [routed] = await db.execute(
      sqlTag`select count(*)::int as n from gsc_page_snapshots_2026_07 where site_id = ${SITE}`,
    );
    expect(routed?.n).toBe(1);
    const rows = await db.execute(
      sqlTag`select clicks from gsc_page_snapshots where site_id = ${SITE}`,
    );
    expect(rows).toHaveLength(1);
    expect(rows[0].clicks).toBe(5);
  });

  test("date hors horizon → partition DEFAULT (filet de sécurité)", async () => {
    await db.insert(domain.gscPageSnapshots).values({
      siteId: SITE,
      date: "2031-01-01",
      page: "/future",
      clicks: 0,
      impressions: 0,
      ctr: 0,
      position: 0,
    });
    const [d] = await db.execute(
      sqlTag`select count(*)::int as n from gsc_page_snapshots_default where site_id = ${SITE}`,
    );
    expect(d?.n).toBe(1);
  });

  test("delete du site → cascade à travers les partitions", async () => {
    await db.insert(domain.gscPageSnapshots).values({
      siteId: SITE,
      date: "2026-07-15",
      page: "/a",
      clicks: 1,
      impressions: 10,
      ctr: 0.1,
      position: 3.2,
    });
    const { eq } = await import("drizzle-orm");
    await db.delete(domain.sites).where(eq(domain.sites.id, SITE));
    const rows = await db.execute(
      sqlTag`select 1 from gsc_page_snapshots where site_id = ${SITE}`,
    );
    expect(rows).toHaveLength(0);
  });
});
