import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";

/**
 * Endereco completo para coordenada, via Nominatim (OpenStreetMap).
 *
 * O CEP sozinho so localiza a faixa dele — em cidade pequena, isso pode ser a
 * cidade inteira, nao a rua. Esta rota geocodifica o endereco por extenso
 * (rua, numero, bairro, cidade), que da um pino muito mais proximo do lugar
 * real. O CEP continua util para preencher o formulario rapido; esta busca e
 * o refino que roda depois, quando o endereco esta completo.
 *
 * Nominatim e gratuito mas pede uso comedido: no maximo 1 pedido por segundo
 * e um User-Agent que identifique quem esta chamando. O atraso aqui garante
 * isso mesmo se duas pessoas buscarem endereco ao mesmo tempo.
 */

export const dynamic = "force-dynamic";

type Coord = { lat: number; lng: number } | null;

const CACHE_MS = 24 * 60 * 60 * 1000;
const cache = new Map<string, { dados: Coord; expira: number }>();

let ultimaChamada = 0;
const INTERVALO_MIN_MS = 1100;

async function aguardarVez() {
  const espera = ultimaChamada + INTERVALO_MIN_MS - Date.now();
  if (espera > 0) await new Promise((r) => setTimeout(r, espera));
  ultimaChamada = Date.now();
}

export async function GET(req: Request) {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Nao autenticado." }, { status: 401 });

  const endereco = String(new URL(req.url).searchParams.get("endereco") || "").trim();
  if (endereco.length < 6) {
    return NextResponse.json({ error: "Endereço muito curto para localizar." }, { status: 400 });
  }
  if (endereco.length > 300) {
    return NextResponse.json({ error: "Endereço muito longo." }, { status: 400 });
  }

  const chave = endereco.toLowerCase();
  const guardado = cache.get(chave);
  if (guardado && guardado.expira > Date.now()) {
    return NextResponse.json({ ok: true, lat: guardado.dados?.lat ?? null, lng: guardado.dados?.lng ?? null });
  }

  try {
    await aguardarVez();
    const url = `https://nominatim.openstreetmap.org/search?format=jsonv2&limit=1&countrycodes=br&q=${encodeURIComponent(endereco)}`;
    const r = await fetch(url, {
      signal: AbortSignal.timeout(8000),
      headers: {
        "User-Agent": "Ktalogu-Agenda/1.0 (+https://ktalogu.com.br)",
        "Accept-Language": "pt-BR",
      },
    });
    if (!r.ok) throw new Error("falhou");
    const lista = (await r.json()) as Array<{ lat: string; lon: string }>;
    const achado: Coord = lista[0] ? { lat: Number(lista[0].lat), lng: Number(lista[0].lon) } : null;
    cache.set(chave, { dados: achado, expira: Date.now() + CACHE_MS });
    return NextResponse.json({ ok: true, lat: achado?.lat ?? null, lng: achado?.lng ?? null });
  } catch {
    return NextResponse.json({ error: "Não consegui localizar esse endereço agora." }, { status: 503 });
  }
}
