import { getAppUrl } from "@/lib/env";

export function getThreadsRedirectUri() {
  return (
    process.env.THREADS_REDIRECT_URI ??
    process.env.THREADS_SOCIAL_REDIRECT_URI ??
    `${getAppUrl()}/connected-accounts/oauth/threads/callback`
  );
}

export function getThreadsConfig() {
  return {
    appId:
      process.env.THREADS_APP_ID?.trim() ||
      process.env.META_APP_ID?.trim() ||
      process.env.FACEBOOK_APP_ID?.trim() ||
      process.env.FACEBOOK_CLIENT_ID?.trim() ||
      "",
    appSecret:
      process.env.THREADS_APP_SECRET?.trim() ||
      process.env.META_APP_SECRET?.trim() ||
      process.env.FACEBOOK_APP_SECRET?.trim() ||
      process.env.FACEBOOK_CLIENT_SECRET?.trim() ||
      "",
    redirectUri: getThreadsRedirectUri(),
    scopes: (
      process.env.THREADS_SCOPES?.trim() ||
      "threads_basic,threads_content_publish,threads_manage_insights"
    )
      .split(/[,\s]+/)
      .filter(Boolean),
    graphVersion: process.env.THREADS_GRAPH_VERSION?.trim() || "v21.0",
  };
}

export function getThreadsGraphBase() {
  const { graphVersion } = getThreadsConfig();
  return `https://graph.threads.net/${graphVersion}`;
}

export function buildThreadsAuthUrl(state: string): string {
  const { appId, redirectUri, scopes } = getThreadsConfig();
  if (!appId || !redirectUri) {
    throw new Error("Threads OAuth is not configured");
  }
  const params = new URLSearchParams({
    client_id: appId,
    redirect_uri: redirectUri,
    scope: scopes.join(","),
    response_type: "code",
    state,
  });
  return `https://threads.net/oauth/authorize?${params.toString()}`;
}

export async function exchangeThreadsCode(code: string): Promise<{
  accessToken: string;
  userId: string;
  expiresIn?: number;
}> {
  const { appId, appSecret, redirectUri } = getThreadsConfig();
  const params = new URLSearchParams({
    client_id: appId,
    client_secret: appSecret,
    grant_type: "authorization_code",
    redirect_uri: redirectUri,
    code,
  });
  const res = await fetch(`https://graph.threads.net/oauth/access_token`, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: params.toString(),
  });
  const data = (await res.json()) as {
    access_token?: string;
    user_id?: number | string;
    expires_in?: number;
    error?: { message?: string };
    error_message?: string;
  };
  if (!res.ok || !data.access_token) {
    throw new Error(
      data.error?.message || data.error_message || "Threads token exchange failed",
    );
  }

  // Long-lived token
  const longParams = new URLSearchParams({
    grant_type: "th_exchange_token",
    client_secret: appSecret,
    access_token: data.access_token,
  });
  const longRes = await fetch(
    `https://graph.threads.net/access_token?${longParams.toString()}`,
  );
  const longData = (await longRes.json()) as {
    access_token?: string;
    expires_in?: number;
  };

  return {
    accessToken: longData.access_token || data.access_token,
    userId: String(data.user_id ?? ""),
    expiresIn: longData.expires_in ?? data.expires_in,
  };
}

export async function fetchThreadsProfile(
  accessToken: string,
): Promise<{ id: string; username: string }> {
  const base = getThreadsGraphBase();
  const res = await fetch(
    `${base}/me?fields=id,username&access_token=${encodeURIComponent(accessToken)}`,
  );
  const data = (await res.json()) as {
    id?: string;
    username?: string;
    error?: { message?: string };
  };
  if (!res.ok || !data.id) {
    throw new Error(data.error?.message || "Failed to load Threads profile");
  }
  return { id: data.id, username: data.username || data.id };
}
