import { NextResponse } from "next/server";
import {
  EterraClient,
  type EsriGeometry,
} from "@/modules/parcel-sync/services/eterra-client";
import { LAYER_CATALOG } from "@/modules/parcel-sync/services/eterra-layers";
import { fetchUatGeometry } from "@/modules/parcel-sync/services/uat-geometry";
import { getSessionCredentials } from "@/modules/parcel-sync/services/session-store";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

type Body = {
  username?: string;
  password?: string;
  siruta?: string | number;
  layerIds?: string[]; // subset — omit to count all
};

/**
 * POST — Count features per layer on the remote eTerra server.
 * Supports session-based auth (falls back to env vars).
 */
export async function POST(req: Request) {
  try {
    const body = (await req.json()) as Body;
    const session = getSessionCredentials();
    const username = String(
      body.username || session?.username || process.env.ETERRA_USERNAME || "",
    ).trim();
    const password = String(
      body.password || session?.password || process.env.ETERRA_PASSWORD || "",
    ).trim();
    const siruta = String(body.siruta ?? "").trim();

    if (!username || !password)
      return NextResponse.json({ error: "Credențiale lipsă" }, { status: 400 });
    if (!/^\d+$/.test(siruta))
      return NextResponse.json({ error: "SIRUTA invalid" }, { status: 400 });

    const client = await EterraClient.create(username, password);
    let uatGeometry: EsriGeometry | undefined;

    // Pre-fetch UAT geometry for spatial layers
    try {
      uatGeometry = await fetchUatGeometry(client, siruta);
    } catch {
      // Some layers don't need it
    }

    const layers = body.layerIds
      ? LAYER_CATALOG.filter((l) => body.layerIds!.includes(l.id))
      : LAYER_CATALOG;

    const results: Record<string, { count: number; error?: string }> = {};

    // Count layers in parallel, max 4 concurrent
    const chunks: (typeof layers)[] = [];
    for (let i = 0; i < layers.length; i += 4) {
      chunks.push(layers.slice(i, i + 4));
    }

    for (const chunk of chunks) {
      const promises = chunk.map(async (layer) => {
        try {
          const count =
            layer.spatialFilter && uatGeometry
              ? await client.countLayerByGeometry(layer, uatGeometry)
              : await client.countLayer(layer, siruta);
          results[layer.id] = { count };
        } catch (err) {
          results[layer.id] = {
            count: 0,
            error: err instanceof Error ? err.message : "eroare",
          };
        }
      });
      await Promise.all(promises);
    }

    return NextResponse.json({ siruta, counts: results });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Eroare server";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}
