import getCycleTLS from "./cycletls.js";
import { decodeJetfuel } from "./parsers/jetfuel.js";

const JFAPI_BASE = "https://x.com/i/jfapi";
const JF_MOUNT = "https://x.com/i/jf";
const JF_ORIGIN = "https://jf.x.com";

export default async function jetfuel(route, opts = {}) {
  if (!this.auth) throw new Error("must be logged in before calling jetfuel");

  const {
    params,
    method = "GET",
    body,
    theme = "business", // fuck it why not
    jfVersion = "JP-5",
    headers,
    referer,
    origin = "jfapi",
  } = opts;

  const cleanRoute = String(route).replace(/^\/+/, "");
  let finalUrl = `${origin === "jf" ? JF_ORIGIN : JFAPI_BASE}/${cleanRoute}`;

  if (params && Object.keys(params).length) {
    const searchParams = new URLSearchParams(params);
    const separator = finalUrl.includes("?") ? "&" : "?";
    finalUrl = `${finalUrl}${separator}${searchParams.toString()}`;
  }

  const url = new URL(finalUrl);
  const pathname = url.pathname;
  const routePath = cleanRoute.split("?")[0];

  const requestHeaders = {
    accept: "*/*",
    "accept-language": "en",
    authorization: `Bearer ${this.auth.client.bearer}`,
    "x-csrf-token": this.auth.csrfToken,
    "x-twitter-active-user": "yes",
    "x-twitter-auth-type": "OAuth2Session",
    "x-twitter-client-language": "en",
    "x-jf-client-theme": theme,
    "x-jf-v": jfVersion,
    priority: "u=1, i",
    "sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"macOS"',
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "sec-gpc": "1",
    cookie:
      this.auth.client.headers.cookie + (this.elevatedCookies ? `; ${this.elevatedCookies}` : ""),
    ...headers,
  };

  if (this.auth.generateTransactionId) {
    requestHeaders["x-client-transaction-id"] = await this.auth.generateTransactionId(
      method.toUpperCase(),
      pathname,
    );
  }

  const cycleTLS = await getCycleTLS();
  const res = await cycleTLS(
    finalUrl,
    {
      headers: requestHeaders,
      userAgent: this.auth.client.fingerprints.userAgent,
      ja3: this.auth.client.fingerprints.ja3,
      ja4r: this.auth.client.fingerprints.ja4r,
      body: body || undefined,
      proxy: this.proxy || undefined,
      referrer: referer || `${JF_MOUNT}/${routePath}`,
      responseType: "arraybuffer",
    },
    method,
  );

  const buffer = Buffer.from(await res.arrayBuffer());
  const contentType = res.headers["content-type"] || res.headers["Content-Type"] || null;

  return {
    status: res.status,
    headers: res.headers,
    contentType: Array.isArray(contentType) ? contentType[0] : contentType,
    buffer,
    text: () => buffer.toString("utf8"),
    decode: () => decodeJetfuel(buffer),
  };
}
