function normalizeControlUrl(value) {
  const raw = String(value || "").trim();
  if (!raw) return "";
  const withProtocol = /^https?:\/\//i.test(raw) ? raw : `http://${raw}`;
  const url = new URL(withProtocol);
  if (!["http:", "https:"].includes(url.protocol)) {
    throw new Error("Gateway URL must use http or https");
  }
  url.hash = "";
  url.search = "";
  url.pathname = url.pathname.replace(/\/api\/shared-proxy\/?$/, "") || "/";
  return url.toString().replace(/\/$/, "");
}

function proxyHostFromHeader(hostHeader) {
  const raw = String(hostHeader || "").trim();
  if (!raw) return "";
  if (raw.startsWith("[")) {
    const end = raw.indexOf("]");
    return end > 0 ? raw.slice(1, end) : "";
  }
  return raw.split(":")[0];
}

function normalizeProxyInfo(proxy) {
  if (!proxy || typeof proxy !== "object") return null;
  const host = String(proxy.host || "").trim();
  const port = Number.parseInt(proxy.port, 10);
  const protocol = proxy.protocol === "http" ? "http" : "socks5";
  if (!host || !Number.isInteger(port) || port <= 0 || port > 65535) {
    return null;
  }
  return { host, port, protocol };
}

export function buildSharedProxyInfo({
  appMode,
  proxyPort,
  running,
  hostHeader,
  sharedProxyHost,
}) {
  const host = String(sharedProxyHost || "").trim() || proxyHostFromHeader(hostHeader);
  const port = Number.parseInt(proxyPort, 10);
  const available =
    appMode === "gateway" &&
    Boolean(running) &&
    host &&
    Number.isInteger(port) &&
    port > 0 &&
    port <= 65535;

  const proxy = available
    ? {
        host,
        port,
        protocol: "socks5",
        httpUrl: `http://${host}:${port}`,
        socksUrl: `socks5://${host}:${port}`,
      }
    : null;

  return {
    success: true,
    available,
    mode: appMode,
    proxy,
  };
}

export async function checkSharedProxyGateway(controlUrl, fetchImpl = fetch) {
  const baseUrl = normalizeControlUrl(controlUrl);
  const response = await fetchImpl(`${baseUrl}/api/shared-proxy`, {
    headers: { accept: "application/json" },
  });
  const data = await response.json().catch(() => ({}));
  if (!response.ok || data.success === false) {
    throw new Error(data.error || `Gateway returned ${response.status}`);
  }
  if (!data.available) {
    throw new Error("Gateway shared proxy is not available");
  }

  const sharedProxy = normalizeProxyInfo(data.proxy);
  if (!sharedProxy) {
    throw new Error("Gateway returned invalid shared proxy settings");
  }

  return {
    sharedProxyEnabled: true,
    sharedProxyControlUrl: baseUrl,
    sharedProxy,
  };
}
