import { NextResponse } from "next/server";
import { Query } from "node-appwrite";

import { DATABASE_ID, TABLES } from "@/lib/appwrite/schema";
import { createAdminClient } from "@/lib/appwrite/server";
import { requireTenant } from "@/lib/appwrite/tenant-guard";

const TENANT_TABLES = [
  TABLES.tenantSettings,
  TABLES.profiles,
  TABLES.connections,
  TABLES.patients,
  TABLES.clinicPricing,
  TABLES.jobs,
  TABLES.jobFiles,
  TABLES.jobStatusHistory,
  TABLES.prosthetics,
  TABLES.financeEntries,
  TABLES.payments,
  TABLES.notifications,
  TABLES.auditLogs,
] as const;

const TENANT_FIELDS_BY_TABLE: Record<string, string[]> = {
  // Most tables use 'tenantId' or 'clinicTenantId'/'labTenantId' for ownership.
  [TABLES.tenantSettings]: ["tenantId"],
  [TABLES.profiles]: ["tenantId"],
  [TABLES.connections]: ["clinicTenantId", "labTenantId"],
  [TABLES.patients]: ["clinicTenantId"],
  [TABLES.clinicPricing]: ["labTenantId", "clinicTenantId"],
  [TABLES.jobs]: ["clinicTenantId", "labTenantId"],
  [TABLES.jobFiles]: ["clinicTenantId", "labTenantId"],
  [TABLES.jobStatusHistory]: ["clinicTenantId", "labTenantId"],
  [TABLES.prosthetics]: ["tenantId"],
  [TABLES.financeEntries]: ["tenantId"],
  [TABLES.payments]: ["tenantId", "counterpartTenantId"],
  [TABLES.notifications]: ["tenantId"],
  [TABLES.auditLogs]: ["tenantId"],
};

/**
 * Return a JSON file containing every row this tenant has access to.
 * Used for KVKK 'data portability' and as a sanity-check pre-delete.
 */
export async function GET() {
  let ctx;
  try {
    ctx = await requireTenant();
  } catch {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { tablesDB } = createAdminClient();
  const out: Record<string, unknown[]> = {};

  for (const table of TENANT_TABLES) {
    const fields = TENANT_FIELDS_BY_TABLE[table] ?? ["tenantId"];
    try {
      // Fetch each row where ANY of the ownership fields equals our tenantId.
      // For tables with two fields (jobs, connections, ...) issue both queries
      // and dedupe — Appwrite doesn't have OR across distinct equality terms.
      const seen = new Set<string>();
      const rows: unknown[] = [];
      for (const field of fields) {
        const result = await tablesDB.listRows({
          databaseId: DATABASE_ID,
          tableId: table,
          queries: [Query.equal(field, ctx.tenantId), Query.limit(500)],
        });
        for (const r of result.rows) {
          const id = (r as { $id?: string }).$id;
          if (id && !seen.has(id)) {
            seen.add(id);
            rows.push(r);
          }
        }
      }
      out[table] = rows;
    } catch (e) {
      out[table] = [
        { error: e instanceof Error ? e.message : "fetch failed" },
      ];
    }
  }

  const payload = {
    exportedAt: new Date().toISOString(),
    tenantId: ctx.tenantId,
    tenantKind: ctx.kind,
    requestedBy: { id: ctx.user.id, email: ctx.user.email, name: ctx.user.name },
    data: out,
  };

  const fileName = `dls-export-${ctx.tenantId}-${Date.now()}.json`;
  return new NextResponse(JSON.stringify(payload, null, 2), {
    status: 200,
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      "Content-Disposition": `attachment; filename="${fileName}"`,
      "Cache-Control": "private, no-store",
    },
  });
}
