/**
 * POST /api/eterra/refresh-all
 *
 * Runs delta sync on ALL UATs in DB sequentially.
 * UATs with >30% enrichment → magic mode (sync + enrichment).
 * UATs with ≤30% enrichment → base mode (sync only).
 *
 * Returns immediately with jobId — progress via /api/eterra/progress.
 */

import { PrismaClient } from "@prisma/client";
import {
  setProgress,
  clearProgress,
  type SyncProgress,
} from "@/modules/parcel-sync/services/progress-store";
import { syncLayer } from "@/modules/parcel-sync/services/sync-service";
import { enrichFeatures } from "@/modules/parcel-sync/services/enrich-service";
import { EterraClient } from "@/modules/parcel-sync/services/eterra-client";
import { checkEterraHealthNow } from "@/modules/parcel-sync/services/eterra-health";

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

const prisma = new PrismaClient();

export async function POST() {
  const username = process.env.ETERRA_USERNAME ?? "";
  const password = process.env.ETERRA_PASSWORD ?? "";
  if (!username || !password) {
    return Response.json(
      { error: "ETERRA_USERNAME / ETERRA_PASSWORD not configured" },
      { status: 500 },
    );
  }

  const jobId = crypto.randomUUID();
  setProgress({
    jobId,
    downloaded: 0,
    total: 100,
    status: "running",
    phase: "Pregătire refresh complet",
  });

  void runRefreshAll(jobId, username, password);

  return Response.json({ jobId, message: "Refresh complet pornit" }, { status: 202 });
}

async function runRefreshAll(jobId: string, username: string, password: string) {
  const push = (p: Partial<SyncProgress>) =>
    setProgress({ jobId, downloaded: 0, total: 100, status: "running", ...p } as SyncProgress);

  try {
    // Health check
    const health = await checkEterraHealthNow();
    if (!health.available) {
      setProgress({ jobId, downloaded: 0, total: 100, status: "error", phase: "eTerra indisponibil", message: health.message ?? "maintenance" });
      setTimeout(() => clearProgress(jobId), 3_600_000);
      return;
    }

    // Find all UATs with features + enrichment ratio
    const uats = await prisma.$queryRawUnsafe<
      Array<{ siruta: string; name: string | null; total: number; enriched: number }>
    >(
      `SELECT f.siruta, u.name, COUNT(*)::int as total,
       COUNT(*) FILTER (WHERE f."enrichedAt" IS NOT NULL)::int as enriched
       FROM "GisFeature" f LEFT JOIN "GisUat" u ON f.siruta = u.siruta
       WHERE f."layerId" IN ('TERENURI_ACTIVE','CLADIRI_ACTIVE') AND f."objectId" > 0
       GROUP BY f.siruta, u.name ORDER BY total DESC`,
    );

    if (uats.length === 0) {
      setProgress({ jobId, downloaded: 100, total: 100, status: "done", phase: "Niciun UAT in DB" });
      setTimeout(() => clearProgress(jobId), 3_600_000);
      return;
    }

    const results: Array<{ siruta: string; name: string; mode: string; duration: number; note: string }> = [];
    let errors = 0;

    for (let i = 0; i < uats.length; i++) {
      const uat = uats[i]!;
      const uatName = uat.name ?? uat.siruta;
      const ratio = uat.total > 0 ? uat.enriched / uat.total : 0;
      const isMagic = ratio > 0.3;
      const mode = isMagic ? "magic" : "base";
      const pct = Math.round(((i) / uats.length) * 100);

      push({
        downloaded: pct,
        total: 100,
        phase: `[${i + 1}/${uats.length}] ${uatName} (${mode})`,
        note: results.length > 0 ? `Ultimul: ${results[results.length - 1]!.name} — ${results[results.length - 1]!.note}` : undefined,
      });

      const uatStart = Date.now();
      try {
        // Sync TERENURI + CLADIRI (quick-count + VALID_FROM delta)
        const tRes = await syncLayer(username, password, uat.siruta, "TERENURI_ACTIVE", { uatName });
        const cRes = await syncLayer(username, password, uat.siruta, "CLADIRI_ACTIVE", { uatName });

        let enrichNote = "";
        if (isMagic) {
          const client = await EterraClient.create(username, password, { timeoutMs: 120_000 });
          const eRes = await enrichFeatures(client, uat.siruta);
          enrichNote = eRes.status === "done"
            ? ` | enrich: ${eRes.enrichedCount}/${eRes.totalFeatures ?? "?"}`
            : ` | enrich err: ${eRes.error}`;
        }

        const dur = Math.round((Date.now() - uatStart) / 1000);
        const parts = [
          tRes.newFeatures > 0 || (tRes.validFromUpdated ?? 0) > 0
            ? `T:+${tRes.newFeatures}/${tRes.validFromUpdated ?? 0}vf`
            : "T:ok",
          cRes.newFeatures > 0 || (cRes.validFromUpdated ?? 0) > 0
            ? `C:+${cRes.newFeatures}/${cRes.validFromUpdated ?? 0}vf`
            : "C:ok",
        ];
        const note = `${parts.join(", ")}${enrichNote} (${dur}s)`;
        results.push({ siruta: uat.siruta, name: uatName, mode, duration: dur, note });
        console.log(`[refresh-all] ${i + 1}/${uats.length} ${uatName}: ${note}`);
      } catch (err) {
        errors++;
        const dur = Math.round((Date.now() - uatStart) / 1000);
        const msg = err instanceof Error ? err.message : "Unknown";
        results.push({ siruta: uat.siruta, name: uatName, mode, duration: dur, note: `ERR: ${msg}` });
        console.error(`[refresh-all] ${uatName}: ${msg}`);
      }
    }

    const totalDur = results.reduce((s, r) => s + r.duration, 0);
    const summary = `${uats.length} UATs, ${errors} erori, ${totalDur}s total`;
    setProgress({
      jobId,
      downloaded: 100,
      total: 100,
      status: "done",
      phase: "Refresh complet finalizat",
      message: summary,
      note: results.map((r) => `${r.name}: ${r.note}`).join("\n"),
    });
    console.log(`[refresh-all] Done: ${summary}`);
    setTimeout(() => clearProgress(jobId), 6 * 3_600_000);
  } catch (err) {
    const msg = err instanceof Error ? err.message : "Unknown";
    setProgress({ jobId, downloaded: 0, total: 100, status: "error", phase: "Eroare", message: msg });
    setTimeout(() => clearProgress(jobId), 3_600_000);
  }
}
