import { getLinkedInConfig } from "@/lib/env";
import {
  linkedInReconnectHint,
  validateLinkedInScopes,
} from "@/lib/social/linkedin-scopes";

const INVALID_IDS = new Set(["unknown", "linkedin-connected", ""]);

export function isValidLinkedInMemberId(id: string | null | undefined): boolean {
  if (!id) return false;
  if (INVALID_IDS.has(id)) return false;
  if (id.startsWith("urn:li:person:")) return true;
  return /^[A-Za-z0-9_-]+$/.test(id);
}

function toPersonUrn(id: string): string {
  if (id.startsWith("urn:li:person:")) return id;
  return `urn:li:person:${id}`;
}

export interface LinkedInProbeResult {
  ok: boolean;
  memberId?: string;
  personUrn?: string;
  attempts: Array<{ endpoint: string; status: number; body?: string }>;
  needsReconnect: boolean;
  recommendation: string;
  scopeMode?: string;
}

/** Test a LinkedIn access token and return detailed API results (no throw). */
export async function probeLinkedInAccessToken(
  accessToken: string,
  externalId?: string | null,
): Promise<LinkedInProbeResult> {
  const attempts: LinkedInProbeResult["attempts"] = [];
  const scopeValidation = validateLinkedInScopes(getLinkedInConfig().scopes);

  if (isValidLinkedInMemberId(externalId)) {
    return {
      ok: true,
      memberId: externalId!.replace(/^urn:li:person:/, ""),
      personUrn: toPersonUrn(externalId!),
      attempts,
      needsReconnect: false,
      recommendation: "Stored member ID is valid.",
      scopeMode: scopeValidation.mode,
    };
  }

  const auth = { Authorization: `Bearer ${accessToken}` };
  const restli = { ...auth, "X-Restli-Protocol-Version": "2.0.0" };

  // Legacy tokens (r_liteprofile) — try /v2/me first
  const meRes = await fetch("https://api.linkedin.com/v2/me?projection=(id,localizedFirstName,localizedLastName)", {
    headers: restli,
  });
  if (meRes.ok) {
    const me = (await meRes.json()) as { id?: string };
    if (isValidLinkedInMemberId(me.id)) {
      return {
        ok: true,
        memberId: me.id!,
        personUrn: toPersonUrn(me.id!),
        attempts,
        needsReconnect: false,
        recommendation: "Token is valid (v2/me — legacy or OpenID).",
        scopeMode: scopeValidation.mode,
      };
    }
  } else {
    attempts.push({
      endpoint: "v2/me",
      status: meRes.status,
      body: (await meRes.text()).slice(0, 300),
    });
  }

  // OpenID tokens
  const userinfoRes = await fetch("https://api.linkedin.com/v2/userinfo", { headers: auth });
  if (userinfoRes.ok) {
    const profile = (await userinfoRes.json()) as { sub?: string };
    if (isValidLinkedInMemberId(profile.sub)) {
      return {
        ok: true,
        memberId: profile.sub!,
        personUrn: toPersonUrn(profile.sub!),
        attempts,
        needsReconnect: false,
        recommendation: "Token is valid (userinfo — OpenID).",
        scopeMode: scopeValidation.mode,
      };
    }
  } else {
    attempts.push({
      endpoint: "userinfo",
      status: userinfoRes.status,
      body: (await userinfoRes.text()).slice(0, 300),
    });
  }

  const restRes = await fetch("https://api.linkedin.com/rest/me", {
    headers: { ...auth, "LinkedIn-Version": "202405" },
  });
  if (restRes.ok) {
    const me = (await restRes.json()) as { id?: string };
    if (isValidLinkedInMemberId(me.id)) {
      return {
        ok: true,
        memberId: me.id!,
        personUrn: toPersonUrn(me.id!),
        attempts,
        needsReconnect: false,
        recommendation: "Token is valid (rest/me).",
        scopeMode: scopeValidation.mode,
      };
    }
  } else {
    attempts.push({
      endpoint: "rest/me",
      status: restRes.status,
      body: (await restRes.text()).slice(0, 300),
    });
  }

  let recommendation = linkedInReconnectHint(scopeValidation);

  if (!scopeValidation.valid) {
    recommendation =
      "LINKEDIN_SCOPES is misconfigured on the server. " +
      (scopeValidation.mode === "invalid"
        ? "Use r_liteprofile r_emailaddress w_member_social (legacy) OR openid profile email w_member_social (OpenID)."
        : linkedInReconnectHint(scopeValidation));
  } else if (scopeValidation.mode === "openid") {
    recommendation =
      "Token missing openid permissions. Disconnect LinkedIn, confirm OpenID product is enabled in LinkedIn Developer Portal, restart app, reconnect.";
  } else if (scopeValidation.mode === "legacy") {
    recommendation =
      "Token missing r_liteprofile. Set LINKEDIN_SCOPES=r_liteprofile r_emailaddress w_member_social, restart app, disconnect and reconnect LinkedIn.";
  }

  return {
    ok: false,
    attempts,
    needsReconnect: true,
    recommendation,
    scopeMode: scopeValidation.mode,
  };
}
