import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import {
  canAccessExperienciometro,
  ensureExperienceBaseline,
  getActiveExperiencePolicy,
  mapExperiencePolicy,
  mapLocationSummary,
} from "@/lib/experienciometro";

export async function GET(request: Request) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canAccessExperienciometro(session.user.role)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  await ensureExperienceBaseline(prisma, session.user.id);

  const [policyRaw, locationsRaw] = await Promise.all([
    getActiveExperiencePolicy(prisma),
    prisma.location.findMany({
      where: { isActive: true },
      include: {
        managerUser: {
          select: {
            name: true,
            email: true,
          },
        },
        metrics: {
          select: {
            currentScore: true,
            signal: true,
            trendDelta: true,
            trendDirection: true,
            lastEvaluationAt: true,
            totalEvaluations: true,
            openFindings: true,
          },
        },
      },
      orderBy: [{ name: "asc" }],
    }),
  ]);

  const policy = mapExperiencePolicy(policyRaw);
  const url = new URL(request.url);
  const q = url.searchParams.get("q")?.trim().toLowerCase() ?? "";
  const signalFilter = url.searchParams.get("signal")?.trim().toLowerCase();
  const minScore = Number(url.searchParams.get("minScore") ?? "");
  const maxScore = Number(url.searchParams.get("maxScore") ?? "");

  const locations = locationsRaw
    .map(mapLocationSummary)
    .filter((location) => {
      if (q) {
        const haystack = `${location.name} ${location.code} ${location.city ?? ""}`.toLowerCase();
        if (!haystack.includes(q)) {
          return false;
        }
      }

      if (signalFilter && signalFilter !== "all" && location.signal !== signalFilter) {
        return false;
      }

      if (Number.isFinite(minScore) && location.score < minScore) {
        return false;
      }

      if (Number.isFinite(maxScore) && location.score > maxScore) {
        return false;
      }

      return true;
    })
    .sort((a, b) => {
      if (b.score !== a.score) {
        return b.score - a.score;
      }
      return a.name.localeCompare(b.name, "es");
    });

  return NextResponse.json({
    ok: true,
    generatedAt: new Date().toISOString(),
    policy,
    locations,
  });
}
