import { ClientTransaction, handleXMigration } from "x-client-transaction-id";
import getCycleTLS from "./cycletls.js";

const GROK_BASE = "https://api.x.com/2/grok";

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

  const { method = "POST", body, params, headers } = opts;

  const cleanRoute = String(route).replace(/^\/+/, "");
  let finalUrl = `${GROK_BASE}/${cleanRoute}`;

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

  const pathname = new URL(finalUrl).pathname;

  if (!this.auth.generateTransactionId) {
    const document = await handleXMigration();
    const transaction = new ClientTransaction(document);
    await transaction.initialize();
    this.auth.generateTransactionId = transaction.generateTransactionId.bind(transaction);
  }

  const requestHeaders = {
    accept: "*/*",
    "accept-language": "en-US,en;q=0.9",
    authorization: `Bearer ${this.auth.client.bearer}`,
    "content-type": "application/json",
    "x-csrf-token": this.auth.csrfToken,
    "x-twitter-active-user": "yes",
    "x-twitter-auth-type": "OAuth2Session",
    "x-twitter-client-language": "en",
    "x-client-transaction-id": await this.auth.generateTransactionId(method.toUpperCase(), pathname),
    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-site",
    "sec-gpc": "1",
    cookie:
      this.auth.client.headers.cookie + (this.elevatedCookies ? `; ${this.elevatedCookies}` : ""),
    ...headers,
  };

  const requestBody =
    body == null ? undefined : typeof body === "string" ? body : JSON.stringify(body);

  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: requestBody,
      proxy: this.proxy || undefined,
      referrer: "https://x.com/",
    },
    method,
  );

  const text = await res.text();
  return {
    status: res.status,
    headers: res.headers,
    text,
    json: () => JSON.parse(text),
  };
}
