/**
 * Proxy utility — fetches next available proxy from TIP proxy pool.
 * Falls back to process.env.PROXY_URL if pool is empty or unreachable.
 */
import * as https from "https";
import * as http from "http";

const TIP_API = process.env.TIP_API_URL ?? "https://transceiver-db.context-x.org";
const FALLBACK = process.env.PROXY_URL ?? "";

interface ProxyResponse {
  success: boolean;
  host: string;
  port: number;
  protocol: string;
}

function getJson(url: string): Promise<unknown> {
  return new Promise((resolve, reject) => {
    const parsed = new URL(url);
    const mod = parsed.protocol === "https:" ? https : http;

    const req = mod.request(
      {
        hostname: parsed.hostname,
        port: parsed.port || (parsed.protocol === "https:" ? 443 : 80),
        path: parsed.pathname + parsed.search,
        method: "GET",
        headers: { "User-Agent": "TIP-Scraper/1.0.0" },
        timeout: 5_000,
      },
      (res) => {
        const chunks: Buffer[] = [];
        res.on("data", (c: Buffer) => chunks.push(c));
        res.on("end", () => {
          try {
            resolve(JSON.parse(Buffer.concat(chunks).toString()));
          } catch {
            reject(new Error("Invalid JSON response"));
          }
        });
      }
    );

    req.on("timeout", () => { req.destroy(); reject(new Error("timeout")); });
    req.on("error", reject);
    req.end();
  });
}

/**
 * Returns the next available proxy URL from the TIP proxy pool.
 * Format: "socks5://host:port" or "http://host:port"
 * Returns undefined if no proxy is available (direct connection).
 */
export async function getProxyUrl(): Promise<string | undefined> {
  // Try proxy pool first
  try {
    const data = await getJson(`${TIP_API}/api/proxy/next`) as ProxyResponse;
    if (data?.success && data.host && data.port) {
      const protocol = data.protocol ?? "socks5";
      const proxyUrl = `${protocol}://${data.host}:${data.port}`;
      console.log(`[proxy] Using TIP pool node: ${data.host}:${data.port} (${protocol})`);
      return proxyUrl;
    }
  } catch {
    // Pool unavailable — fall through to env fallback
  }

  // Fallback to env var
  if (FALLBACK) {
    console.log(`[proxy] Using env PROXY_URL fallback`);
    return FALLBACK;
  }

  return undefined;
}
