import { NextResponse } from "next/server";
import { prisma } from "@/core/storage/prisma";

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

/**
 * GET /api/eterra/db-summary
 *
 * Returns a summary of ALL data in the GIS database, grouped by UAT.
 * No siruta required — shows everything across all UATs.
 *
 * Response shape:
 * {
 *   uats: [{
 *     siruta, uatName,
 *     layers: [{ layerId, count, enrichedCount, lastSynced }],
 *     totalFeatures, totalEnriched
 *   }],
 *   totalFeatures, totalUats
 * }
 */
export async function GET() {
  try {
    // Feature counts per siruta + layerId
    const featureCounts = await prisma.gisFeature.groupBy({
      by: ["siruta", "layerId"],
      _count: { id: true },
    });

    // Enriched counts per siruta + layerId
    const enrichedCounts = await prisma.gisFeature.groupBy({
      by: ["siruta", "layerId"],
      where: { enrichedAt: { not: null } },
      _count: { id: true },
    });
    const enrichedMap = new Map<string, number>();
    for (const e of enrichedCounts) {
      enrichedMap.set(`${e.siruta}:${e.layerId}`, e._count.id);
    }

    // No-geometry counts per siruta + layerId
    const noGeomCounts = await prisma.gisFeature.groupBy({
      by: ["siruta", "layerId"],
      where: { geometrySource: "NO_GEOMETRY" },
      _count: { id: true },
    });
    const noGeomMap = new Map<string, number>();
    for (const ng of noGeomCounts) {
      noGeomMap.set(`${ng.siruta}:${ng.layerId}`, ng._count.id);
    }

    // Latest sync run per siruta + layerId
    const latestRuns = await prisma.gisSyncRun.findMany({
      where: { status: "done" },
      orderBy: { completedAt: "desc" },
      select: {
        siruta: true,
        uatName: true,
        layerId: true,
        completedAt: true,
      },
    });
    const latestRunMap = new Map<
      string,
      { completedAt: Date | null; uatName: string | null }
    >();
    for (const r of latestRuns) {
      const key = `${r.siruta}:${r.layerId}`;
      if (!latestRunMap.has(key)) {
        latestRunMap.set(key, {
          completedAt: r.completedAt,
          uatName: r.uatName,
        });
      }
    }

    // UAT names from GisUat table
    const uatNames = await prisma.gisUat.findMany({
      select: { siruta: true, name: true, county: true },
    });
    const uatNameMap = new Map<
      string,
      { name: string; county: string | null }
    >();
    for (const u of uatNames) {
      uatNameMap.set(u.siruta, { name: u.name, county: u.county });
    }

    // Group by siruta
    const uatMap = new Map<
      string,
      {
        siruta: string;
        uatName: string;
        county: string | null;
        layers: {
          layerId: string;
          count: number;
          enrichedCount: number;
          noGeomCount: number;
          lastSynced: string | null;
        }[];
        totalFeatures: number;
        totalEnriched: number;
        totalNoGeom: number;
      }
    >();

    for (const fc of featureCounts) {
      if (!uatMap.has(fc.siruta)) {
        const uatInfo = uatNameMap.get(fc.siruta);
        const runInfo = latestRunMap.get(`${fc.siruta}:${fc.layerId}`);
        uatMap.set(fc.siruta, {
          siruta: fc.siruta,
          uatName: uatInfo?.name ?? runInfo?.uatName ?? `UAT ${fc.siruta}`,
          county: uatInfo?.county ?? null,
          layers: [],
          totalFeatures: 0,
          totalEnriched: 0,
          totalNoGeom: 0,
        });
      }

      const uat = uatMap.get(fc.siruta)!;
      const enriched = enrichedMap.get(`${fc.siruta}:${fc.layerId}`) ?? 0;
      const noGeom = noGeomMap.get(`${fc.siruta}:${fc.layerId}`) ?? 0;
      const runInfo = latestRunMap.get(`${fc.siruta}:${fc.layerId}`);

      uat.layers.push({
        layerId: fc.layerId,
        count: fc._count.id,
        enrichedCount: enriched,
        noGeomCount: noGeom,
        lastSynced: runInfo?.completedAt?.toISOString() ?? null,
      });
      uat.totalFeatures += fc._count.id;
      uat.totalEnriched += enriched;
      uat.totalNoGeom += noGeom;

      // Update UAT name if we got one from sync runs
      if (uat.uatName.startsWith("UAT ") && runInfo?.uatName) {
        uat.uatName = runInfo.uatName;
      }
    }

    const uats = Array.from(uatMap.values()).sort(
      (a, b) => b.totalFeatures - a.totalFeatures,
    );

    const totalFeatures = uats.reduce((s, u) => s + u.totalFeatures, 0);

    return NextResponse.json({
      uats,
      totalFeatures,
      totalUats: uats.length,
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Eroare server";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}
