import STATIC from '@/data/tkgm-idari.json';
type Opt = { id: number; text: string };
/**
 * TKGM MEGSİS erişimi.
 * - TKGM bazı veri merkezi IP'lerini (üretim sunucumuz dahil) 403 ile reddediyor; yabancı bir Referer görünce de 403 veriyor.
 * - Erişim yolları (sırayla):
 *   1) TKGM_PROXY_URL tanımlıysa: HTTP(S) vekil sunucu (http://kullanici:sifre@host:port) — Türkiye'de, TKGM'nin engellemediği bir IP.
 *   2) TKGM_API_BASE: TKGM API'sini birebir aktaran bir röle (ör. https://role.ornek.com/megsiswebapi.v3/api).
 *   3) Doğrudan cbsapi.tkgm.gov.tr.
 * - İl/ilçe/mahalle listeleri her zaman paketle gelen kopyadan okunur (TKGM'ye hiç gidilmez).
 */
// Sırayla denenen API tabanları; bir taban kota/engel (403) verirse sıradakine geçilir.
const BASES = [
  ...(process.env.TKGM_API_BASE ? process.env.TKGM_API_BASE.split(',') : []),
  'https://cbsapi.tkgm.gov.tr/megsiswebapi.v3/api',
  'https://cbsapi.tkgm.gov.tr/megsiswebapi.v3.1/api',
].map((b) => b.trim().replace(/\/$/, '')).filter(Boolean);
const RELAY_KEY = process.env.TKGM_RELAY_KEY;
const HEADERS: Record<string, string> = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36', Accept: 'application/json, text/plain, */*', 'Accept-Language': 'tr-TR,tr;q=0.9,en;q=0.8' };
let dispatcher: unknown;
async function getDispatcher() {
  if (!process.env.TKGM_PROXY_URL) return undefined;
  if (!dispatcher) { const { ProxyAgent } = await import('undici'); dispatcher = new ProxyAgent(process.env.TKGM_PROXY_URL); }
  return dispatcher;
}
export async function tkgmFetch(p: string, timeoutMs = 15000, base = BASES[0]) {
  const d = await getDispatcher();
  const h = RELAY_KEY && !base.includes('tkgm.gov.tr') ? { ...HEADERS, 'x-relay-key': RELAY_KEY } : HEADERS;
  if (d) { const { fetch: uf } = await import('undici'); return uf(`${base}/${p}`, { headers: h, signal: AbortSignal.timeout(timeoutMs), dispatcher: d as never }) as unknown as Response; }
  return fetch(`${base}/${p}`, { signal: AbortSignal.timeout(timeoutMs), cache: 'no-store', headers: h });
}
export const TKGM_BASES = BASES;
export const tkgmVia = () => (process.env.TKGM_PROXY_URL ? 'proxy' : process.env.TKGM_API_BASE ? 'relay' : 'direct');

const cache = new Map<string, { at: number; v: unknown }>();
export async function tkgm<T = unknown>(p: string, ttlMs = 86400000): Promise<T> {
  const hit = cache.get(p); if (hit && Date.now() - hit.at < ttlMs) return hit.v as T;
  let last: unknown;
  for (let i = 0; i < 3 + BASES.length; i++) {
    const base = BASES[Math.min(i, BASES.length - 1)];
    try {
      const r = await tkgmFetch(p, 15000, base);
      if (r.status === 404) throw Object.assign(new Error('bulunamadı'), { status: 404 });
      if (r.status === 403) { const b = await r.text().catch(() => ''); throw Object.assign(new Error(/limit/i.test(b) ? 'TKGM günlük sorgu limiti aşıldı (bu IP için)' : 'TKGM 403 (erişim engellendi)'), { status: 403 }); }
      if (!r.ok) throw new Error(`TKGM ${r.status}`);
      const v = await r.json(); cache.set(p, { at: Date.now(), v }); if (cache.size > 2000) cache.delete(cache.keys().next().value!); return v as T;
    } catch (e) {
      last = e; const st = (e as { status?: number }).status;
      console.error('[tkgm]', tkgmVia(), p, (e as { cause?: { code?: string } }).cause?.code || (e as Error).message);
      if (st === 404) break;
      if (st === 403) { if (i >= BASES.length - 1) break; continue; } // kota/engel: sıradaki tabana geç
      await new Promise((s) => setTimeout(s, 500 * (i + 1)));
    }
  }
  throw last;
}
export async function idari(kind: 'il' | 'ilce' | 'mahalle', id?: string): Promise<Opt[]> {
  const st = STATIC as { il: Opt[]; ilce: Record<string, Opt[]> };
  let v: Opt[] | undefined;
  if (kind === 'il') v = st.il;
  else if (kind === 'ilce') v = st.ilce[String(id)];
  else { const mh = (await import('@/data/tkgm-mahalle.json')).default as unknown as Record<string, [number, string][]>; v = mh[String(id)]?.map(([i, t]) => ({ id: i, text: t })); }
  if (!v) throw Object.assign(new Error('bulunamadı'), { status: 404 });
  return [...v].sort((a, b) => a.text.localeCompare(b.text, 'tr'));
}
