/**
 * GET  /api/eterra/sync-rules — List all sync rules, enriched with UAT/county names
 * POST /api/eterra/sync-rules — Create a new sync rule
 */

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

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

const VALID_FREQUENCIES = ["3x-daily", "daily", "weekly", "monthly", "manual"] as const;

/** Compute nextDueAt from lastSyncAt + frequency interval */
function computeNextDue(frequency: string, lastSyncAt: Date | null): Date | null {
  if (frequency === "manual") return null;
  const base = lastSyncAt ?? new Date();
  const ms = {
    "3x-daily": 8 * 3600_000,
    daily: 24 * 3600_000,
    weekly: 7 * 24 * 3600_000,
    monthly: 30 * 24 * 3600_000,
  }[frequency];
  if (!ms) return null;
  return new Date(base.getTime() + ms);
}

export async function GET() {
  try {
    const rules = await prisma.gisSyncRule.findMany({
      orderBy: [{ priority: "asc" }, { createdAt: "desc" }],
    });

    // Enrich with UAT names for UAT-specific rules
    const sirutas = rules
      .map((r) => r.siruta)
      .filter((s): s is string => s != null);

    const uatMap = new Map<string, string>();
    if (sirutas.length > 0) {
      const uats = await prisma.gisUat.findMany({
        where: { siruta: { in: sirutas } },
        select: { siruta: true, name: true },
      });
      for (const u of uats) uatMap.set(u.siruta, u.name);
    }

    // For county rules, get UAT count per county
    const counties = rules
      .map((r) => r.county)
      .filter((c): c is string => c != null);

    const countyCountMap = new Map<string, number>();
    if (counties.length > 0) {
      const counts = await prisma.gisUat.groupBy({
        by: ["county"],
        where: { county: { in: counties } },
        _count: true,
      });
      for (const c of counts) {
        if (c.county) countyCountMap.set(c.county, c._count);
      }
    }

    const enriched = rules.map((r) => ({
      ...r,
      uatName: r.siruta ? (uatMap.get(r.siruta) ?? null) : null,
      uatCount: r.county ? (countyCountMap.get(r.county) ?? 0) : r.siruta ? 1 : 0,
    }));

    // Get global default
    const globalDefault = await prisma.keyValueStore.findUnique({
      where: { namespace_key: { namespace: "sync-management", key: "global-default" } },
    });

    return NextResponse.json({
      rules: enriched,
      globalDefault: (globalDefault?.value as { frequency?: string })?.frequency ?? "monthly",
    });
  } catch (error) {
    const msg = error instanceof Error ? error.message : "Eroare server";
    return NextResponse.json({ error: msg }, { status: 500 });
  }
}

export async function POST(req: Request) {
  try {
    const body = (await req.json()) as {
      siruta?: string;
      county?: string;
      frequency?: string;
      syncTerenuri?: boolean;
      syncCladiri?: boolean;
      syncNoGeom?: boolean;
      syncEnrich?: boolean;
      priority?: number;
      enabled?: boolean;
      allowedHoursStart?: number | null;
      allowedHoursEnd?: number | null;
      allowedDays?: string | null;
      label?: string | null;
    };

    if (!body.siruta && !body.county) {
      return NextResponse.json({ error: "Trebuie specificat siruta sau judetul" }, { status: 400 });
    }

    if (!body.frequency || !VALID_FREQUENCIES.includes(body.frequency as typeof VALID_FREQUENCIES[number])) {
      return NextResponse.json(
        { error: `Frecventa invalida. Valori permise: ${VALID_FREQUENCIES.join(", ")}` },
        { status: 400 },
      );
    }

    // Validate siruta exists
    if (body.siruta) {
      const uat = await prisma.gisUat.findUnique({ where: { siruta: body.siruta } });
      if (!uat) {
        return NextResponse.json({ error: `UAT ${body.siruta} nu exista` }, { status: 404 });
      }
    }

    // Validate county has UATs
    if (body.county && !body.siruta) {
      const count = await prisma.gisUat.count({ where: { county: body.county } });
      if (count === 0) {
        return NextResponse.json({ error: `Niciun UAT in judetul ${body.county}` }, { status: 404 });
      }
    }

    // Check for existing rule with same scope
    const existing = await prisma.gisSyncRule.findFirst({
      where: {
        siruta: body.siruta ?? null,
        county: body.siruta ? null : (body.county ?? null),
      },
    });
    if (existing) {
      return NextResponse.json(
        { error: "Exista deja o regula pentru acest scope", existingId: existing.id },
        { status: 409 },
      );
    }

    const nextDueAt = computeNextDue(body.frequency, null);

    const rule = await prisma.gisSyncRule.create({
      data: {
        siruta: body.siruta ?? null,
        county: body.siruta ? null : (body.county ?? null),
        frequency: body.frequency,
        syncTerenuri: body.syncTerenuri ?? true,
        syncCladiri: body.syncCladiri ?? true,
        syncNoGeom: body.syncNoGeom ?? false,
        syncEnrich: body.syncEnrich ?? false,
        priority: body.priority ?? 5,
        enabled: body.enabled ?? true,
        allowedHoursStart: body.allowedHoursStart ?? null,
        allowedHoursEnd: body.allowedHoursEnd ?? null,
        allowedDays: body.allowedDays ?? null,
        label: body.label ?? null,
        nextDueAt,
      },
    });

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