/**
 * GDPR Article 15 data-export (KAR-529).
 *
 * Builds the structured object that gets serialised back to the requesting
 * user. The function is pure — it takes an authenticated Supabase client and
 * a user id, executes read-only queries, and returns the assembled payload.
 *
 * Adding a new user-attributable table:
 *   1. Add the table to USER_OWNED_TABLES below.
 *   2. The export route picks it up automatically.
 *
 * Excluded:
 *   - System tables (auth.users — only id is echoed back; password hash etc.
 *     are never readable through this route).
 *   - Audit log of other users' actions — only the requester's own entries.
 *   - Tenant config, master data — these are not user-attributable.
 */
import type { SupabaseClient } from "@supabase/supabase-js"

/**
 * Tables we export when the user asks for their data.
 * Each entry is (table-name, column-that-references-the-user).
 * Order is alphabetical for stable diff output.
 */
export const USER_OWNED_TABLES: ReadonlyArray<readonly [string, string]> = [
  ["assessments", "created_by"],
  ["assessment_responses", "user_id"],
  ["cycle_measurements", "user_id"],
  ["projects", "user_id"],
  ["process_steps", "user_id"],
  ["qaf_uploads", "user_id"],
  ["user_audit_log", "user_id"],
  ["workshop_actions", "user_id"],
] as const

export interface GdprExport {
  generated_at: string
  user_id: string
  schema_version: 1
  profile: Record<string, unknown> | null
  tables: Record<string, unknown[]>
}

/**
 * Build the export payload for `userId`.
 *
 * The Supabase client must be authenticated as `userId` (or as an admin
 * acting on the user's behalf, in which case the admin route must enforce
 * that authorisation separately — this helper does not check it).
 *
 * RLS does the real authorisation: if `userId` does not match the session's
 * `auth.uid()`, every SELECT returns zero rows.
 */
export async function buildGdprExport(
  client: SupabaseClient,
  userId: string,
): Promise<GdprExport> {
  const profileResult = await client
    .from("user_profiles")
    .select("*")
    .eq("auth_user_id", userId)
    .maybeSingle()

  const tables: Record<string, unknown[]> = {}
  for (const [table, column] of USER_OWNED_TABLES) {
    const result = await client.from(table).select("*").eq(column, userId)
    tables[table] = result.data ?? []
  }

  return {
    generated_at: new Date().toISOString(),
    user_id: userId,
    schema_version: 1,
    profile: profileResult.data ?? null,
    tables,
  }
}
