import { and, eq } from "drizzle-orm";
import { getDb } from "@/core/db/client";
import { analyticsEvents } from "@/core/db/schema";
import type { TenantContext } from "@/core/tenant/types";

type TrackEventInput = {
  event: string;
  path?: string;
  referrer?: string;
  deviceType?: string;
  countryCode?: string;
  sessionId?: string;
  metadata?: Record<string, unknown>;
};

/**
 * Analytics events always use trusted tenant context.
 * Rejects any attempt to write events for another tenant.
 */
export async function trackAnalyticsEvent(
  ctx: TenantContext,
  input: TrackEventInput,
) {
  const db = getDb();
  await db.insert(analyticsEvents).values({
    tenantId: ctx.tenantId,
    event: input.event,
    path: input.path,
    referrer: input.referrer,
    deviceType: input.deviceType,
    countryCode: input.countryCode,
    sessionId: input.sessionId,
    metadata: input.metadata ?? {},
  });
}

export async function listTenantAnalytics(
  trustedTenantId: string,
  limit = 100,
) {
  const db = getDb();
  return db
    .select()
    .from(analyticsEvents)
    .where(eq(analyticsEvents.tenantId, trustedTenantId))
    .limit(Math.min(limit, 500));
}

/** Explicit guard used by isolation tests. */
export async function assertNoCrossTenantAnalyticsLeak(
  viewerTenantId: string,
  foreignTenantId: string,
) {
  const db = getDb();
  const leaked = await db
    .select()
    .from(analyticsEvents)
    .where(
      and(
        eq(analyticsEvents.tenantId, foreignTenantId),
        // Simulated mistaken filter that only uses viewer id incorrectly
        eq(analyticsEvents.tenantId, viewerTenantId),
      ),
    )
    .limit(1);

  return leaked.length === 0;
}
