/**
 * Usage Fetcher - Get usage data from provider APIs
 */

import { PROVIDERS } from "../config/constants.ts";
import {
  getAntigravityFetchAvailableModelsUrls,
  ANTIGRAVITY_BASE_URLS,
} from "../config/antigravityUpstream.ts";
import { isUserCallableAntigravityModelId } from "../config/antigravityModelAliases.ts";
import { getGlmQuotaUrl } from "../config/glmProvider.ts";
import { getGitHubCopilotInternalUserHeaders } from "../config/providerHeaderProfiles.ts";
import { safePercentage } from "@/shared/utils/formatting";
import { fetchBailianQuota, type BailianTripleWindowQuota } from "./bailianQuotaFetcher.ts";
import { fetchDeepseekQuota, type DeepseekQuota } from "./deepseekQuotaFetcher.ts";
import {
  fetchOpencodeQuota,
  type OpencodeTripleWindowQuota,
} from "./opencodeQuotaFetcher.ts";
import {
  applyAntigravityClientProfileHeaders,
  getAntigravityBootstrapHeaders,
  getAntigravityClientProfile,
} from "./antigravityClientProfile.ts";
import {
  antigravityUserAgent,
  getAntigravityHeaders,
  getAntigravityLoadCodeAssistMetadata,
} from "./antigravityHeaders.ts";
import {
  getAntigravityRemainingCredits,
  updateAntigravityRemainingCredits,
} from "../executors/antigravity.ts";
import { getCreditsMode } from "./antigravityCredits.ts";
import { CLAUDE_CODE_VERSION, fetchClaudeBootstrap } from "../executors/claudeIdentity.ts";
import { generateAntigravityRequestId, getAntigravitySessionId } from "./antigravityIdentity.ts";
import {
  extractCodeAssistOnboardTierId,
  extractCodeAssistSubscriptionTier,
} from "./codeAssistSubscription.ts";
import { sanitizeErrorMessage } from "../utils/error.ts";

// Quota / usage upstream URLs (overridable for testing or relays).
const CROF_USAGE_URL = process.env.OMNIROUTE_CROF_USAGE_URL ?? "https://crof.ai/usage_api/";
const GEMINI_CLI_USAGE_URL =
  process.env.OMNIROUTE_GEMINI_CLI_USAGE_URL ??
  "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist";
const CODEWHISPERER_BASE_URL =
  process.env.OMNIROUTE_CODEWHISPERER_BASE_URL ?? "https://codewhisperer.us-east-1.amazonaws.com";

// Antigravity API config (credentials from PROVIDERS via credential loader)
const ANTIGRAVITY_CONFIG = {
  quotaApiUrls: getAntigravityFetchAvailableModelsUrls(),
  loadProjectApiUrl: "https://daily-cloudcode-pa.sandbox.googleapis.com/v1internal:loadCodeAssist",
  tokenUrl: "https://oauth2.googleapis.com/token",
  get clientId() {
    return PROVIDERS.antigravity.clientId;
  },
  get clientSecret() {
    return PROVIDERS.antigravity.clientSecret;
  },
  get userAgent() {
    return antigravityUserAgent();
  },
};

// Codex (OpenAI) API config
const CODEX_CONFIG = {
  usageUrl: "https://chatgpt.com/backend-api/wham/usage",
};

// Claude API config
const CLAUDE_CONFIG = {
  oauthUsageUrl: "https://api.anthropic.com/api/oauth/usage",
  usageUrl: "https://api.anthropic.com/v1/organizations/{org_id}/usage",
  settingsUrl: "https://api.anthropic.com/v1/settings",
  apiVersion: "2023-06-01",
};

// Kimi Coding API config
const KIMI_CONFIG = {
  baseUrl: "https://api.kimi.com/coding/v1",
  usageUrl: "https://api.kimi.com/coding/v1/usages",
  apiVersion: "2023-06-01",
};

const NANOGPT_CONFIG = {
  usageUrl: "https://nano-gpt.com/api/subscription/v1/usage",
};

const OPENCODE_GO_QUOTA_URL =
  process.env.OMNIROUTE_OPENCODE_GO_QUOTA_URL ?? "https://api.z.ai/api/monitor/usage/quota/limit";
const OPENCODE_GO_QUOTA_TOTALS = {
  session: 12,
  weekly: 30,
  mcp_monthly: 60,
} as const;
const OPENCODE_GO_QUOTA_ORDER = ["session", "weekly", "mcp_monthly"] as const;
type OpenCodeGoQuotaName = (typeof OPENCODE_GO_QUOTA_ORDER)[number];

// Cursor dashboard usage API config
// The endpoint that powers https://cursor.com/dashboard/spending. Validates the WorkOS
// session via the WorkosCursorSessionToken cookie (format: `${userId}::${jwt}`) and
// rejects requests without a matching Origin/Referer (Invalid origin for state-changing request).
const CURSOR_USAGE_CONFIG = {
  usageUrl: "https://cursor.com/api/dashboard/get-current-period-usage",
  origin: "https://cursor.com",
  referer: "https://cursor.com/dashboard/spending",
  userAgent:
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
};

const MINIMAX_USAGE_CONFIG = {
  minimax: {
    usageUrls: [
      "https://www.minimax.io/v1/token_plan/remains",
      "https://api.minimax.io/v1/api/openplatform/coding_plan/remains",
    ],
  },
  "minimax-cn": {
    usageUrls: [
      "https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains",
      "https://api.minimaxi.com/v1/api/openplatform/coding_plan/remains",
    ],
  },
} as const;

type JsonRecord = Record<string, unknown>;
type UsageQuota = {
  used: number;
  total: number;
  remaining?: number;
  remainingPercentage?: number;
  resetAt: string | null;
  unlimited: boolean;
  /**
   * True when the upstream provider reported the remaining fraction. False
   * means the API didn't include the field and the 0 value here is a sentinel,
   * NOT a confirmed-exhausted state. Antigravity-specific.
   */
  fractionReported?: boolean;
  displayName?: string;
  details?: Array<{
    name: string;
    used: number;
  }>;
  currency?: string;
  grantedBalance?: number;
  toppedUpBalance?: number;
};
type UsageProviderConnection = JsonRecord & {
  id?: string;
  provider?: string;
  accessToken?: string;
  apiKey?: string;
  providerSpecificData?: JsonRecord;
  projectId?: string;
  email?: string;
};
type SubscriptionCacheEntry = {
  data: unknown;
  fetchedAt: number;
};

function toRecord(value: unknown): JsonRecord {
  return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {};
}

function toNumber(value: unknown, fallback = 0): number {
  const parsed =
    typeof value === "number"
      ? value
      : typeof value === "string" && value.trim().length > 0
        ? Number(value)
        : Number.NaN;
  return Number.isFinite(parsed) ? parsed : fallback;
}

function toPercentage(value: unknown): number {
  return Math.max(0, Math.min(100, toNumber(value, 0)));
}

function toTitleCase(value: string): string {
  return value
    .trim()
    .split(/[\s_-]+/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
    .join(" ");
}

function getGlmTokenQuotaName(
  limit: JsonRecord,
  existingQuotas: Record<string, UsageQuota>
): string {
  const unit = toNumber(limit.unit, 0);
  const number = toNumber(limit.number, 0);

  if (unit === 3 && number === 5) return "session";
  if ((unit === 4 && number === 7) || (unit === 3 && number >= 24 * 7)) return "weekly";

  return existingQuotas.session ? "weekly" : "session";
}

function getGlmQuotaDisplayName(quotaName: string): string {
  if (quotaName === "session") return "5 Hours Quota";
  if (quotaName === "weekly") return "Weekly Quota";
  return quotaName;
}

function getOpenCodeGoTokenQuotaName(
  limit: JsonRecord,
  existingQuotas: Record<string, UsageQuota>
): "session" | "weekly" {
  const unit = toNumber(limit.unit, 0);
  const number = toNumber(limit.number, 0);

  if (unit === 3 && number === 5) return "session";
  if (unit === 6 && number === 1) return "weekly";
  if ((unit === 4 && number === 7) || (unit === 3 && number >= 24 * 7)) return "weekly";

  return existingQuotas.session ? "weekly" : "session";
}

function getOpenCodeGoQuotaDisplayName(quotaName: OpenCodeGoQuotaName): string {
  if (quotaName === "session") return "5-hour rolling";
  if (quotaName === "weekly") return "Weekly";
  return "Monthly";
}

function normalizeOpenCodeGoQuotaToken(apiKey: string): string {
  return apiKey.trim().replace(/^Bearer\s+/i, "");
}

function buildOpenCodeGoDollarQuota(
  quotaName: OpenCodeGoQuotaName,
  percentage: unknown,
  resetAt: string | null,
  usedOverride?: unknown,
  details?: UsageQuota["details"]
): UsageQuota {
  const total = OPENCODE_GO_QUOTA_TOTALS[quotaName];
  const percentUsed = toPercentage(percentage);
  const rawUsed = toNumber(usedOverride, Number.NaN);
  const used = roundCurrency(
    Number.isFinite(rawUsed) ? Math.max(0, Math.min(total, rawUsed)) : (total * percentUsed) / 100
  );
  const remaining = roundCurrency(Math.max(0, total - used));
  const remainingPercentage =
    total > 0
      ? clampPercentage(Math.round((remaining / total) * 100))
      : clampPercentage(100 - percentUsed);

  return {
    used,
    total,
    remaining,
    remainingPercentage,
    resetAt,
    unlimited: false,
    displayName: getOpenCodeGoQuotaDisplayName(quotaName),
    currency: "USD",
    details,
  };
}

function orderOpenCodeGoQuotas(quotas: Record<string, UsageQuota>): Record<string, UsageQuota> {
  const ordered: Record<string, UsageQuota> = {};

  for (const key of OPENCODE_GO_QUOTA_ORDER) {
    if (quotas[key]) ordered[key] = quotas[key];
  }

  for (const [key, quota] of Object.entries(quotas)) {
    if (!ordered[key]) ordered[key] = quota;
  }

  return ordered;
}

function getFieldValue(source: unknown, snakeKey: string, camelKey: string): unknown {
  const obj = toRecord(source);
  return obj[snakeKey] ?? obj[camelKey] ?? null;
}

function clampPercentage(value: number): number {
  return Math.max(0, Math.min(100, value));
}

function roundCurrency(value: number): number {
  return Math.round(value * 100) / 100;
}

function toDisplayLabel(value: string): string {
  return value
    .replace(/^copilot[_\s-]*/i, "")
    .split(/[\s_-]+/)
    .filter(Boolean)
    .map((part) => {
      if (/^pro\+$/i.test(part)) return "Pro+";
      if (/^[a-z]{2,}$/.test(part))
        return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
      return part;
    })
    .join(" ")
    .trim();
}

function shouldDisplayGitHubQuota(quota: UsageQuota | null): quota is UsageQuota {
  if (!quota) return false;
  if (quota.unlimited && quota.total <= 0) return false;
  return quota.total > 0 || quota.remainingPercentage !== undefined;
}

function pickFirstNonEmptyString(...values: unknown[]): string | undefined {
  for (const value of values) {
    if (typeof value !== "string") continue;
    const trimmed = value.trim();
    if (trimmed) return trimmed;
  }
  return undefined;
}

function inferMiniMaxPlanLabelFromTotals(models: JsonRecord[]): string | null {
  const maxSessionTotal = models.reduce(
    (maxTotal, model) => Math.max(maxTotal, getMiniMaxSessionTotal(model)),
    0
  );

  if (maxSessionTotal >= 15_000) return "Max";
  if (maxSessionTotal >= 4_500) return "Plus";
  if (maxSessionTotal >= 1_500) return "Starter";
  return null;
}

function getMiniMaxPlanLabel(payload: JsonRecord, models: JsonRecord[] = []): string {
  const raw = pickFirstNonEmptyString(
    getFieldValue(payload, "current_subscribe_title", "currentSubscribeTitle"),
    getFieldValue(payload, "plan_name", "planName"),
    getFieldValue(payload, "plan", "plan"),
    getFieldValue(payload, "current_plan_title", "currentPlanTitle"),
    getFieldValue(payload, "combo_title", "comboTitle")
  );

  if (!raw) return inferMiniMaxPlanLabelFromTotals(models) || "Coding Plan";

  const cleaned = raw
    .replace(/^minimax\s+/i, "")
    .replace(/\bcoding\s+plan\b/gi, "")
    .replace(/\s{2,}/g, " ")
    .trim();

  return cleaned || inferMiniMaxPlanLabelFromTotals(models) || "Coding Plan";
}

function getClaudePlanLabel(...candidates: Array<string | null | undefined>): string | null {
  for (const candidate of candidates) {
    if (typeof candidate !== "string") continue;
    const trimmed = candidate.trim();
    if (
      !trimmed ||
      trimmed.toLowerCase() === "claude code" ||
      trimmed.toLowerCase() === "unknown"
    ) {
      continue;
    }
    return trimmed;
  }
  return null;
}

function createQuotaFromUsage(
  usedValue: unknown,
  totalValue: unknown,
  resetValue: unknown
): UsageQuota {
  const total = Math.max(0, toNumber(totalValue, 0));
  const used = total > 0 ? Math.min(Math.max(0, toNumber(usedValue, 0)), total) : 0;
  const remaining = total > 0 ? Math.max(total - used, 0) : 0;

  return {
    used,
    total,
    remaining,
    remainingPercentage: total > 0 ? clampPercentage((remaining / total) * 100) : 0,
    resetAt: parseResetTime(resetValue),
    unlimited: false,
  };
}

function getMiniMaxQuotaResetAt(
  model: JsonRecord,
  capturedAtMs: number,
  remainsTimeSnakeKey: string,
  remainsTimeCamelKey: string,
  endTimeSnakeKey: string,
  endTimeCamelKey: string
): string | null {
  const remainsMs = toNumber(getFieldValue(model, remainsTimeSnakeKey, remainsTimeCamelKey), 0);
  if (remainsMs > 0) {
    return new Date(capturedAtMs + remainsMs).toISOString();
  }

  return parseResetTime(getFieldValue(model, endTimeSnakeKey, endTimeCamelKey));
}

function isMiniMaxTextQuotaModel(modelName: string): boolean {
  const normalized = modelName.trim().toLowerCase();
  return (
    normalized.startsWith("minimax-m") ||
    normalized.startsWith("coding-plan") ||
    // MiniMax Coding Plan surfaces the text/coding quota under model "general"
    // (media buckets like "video"/"image"/"music" are excluded).
    normalized === "general"
  );
}

function getMiniMaxSessionTotal(model: JsonRecord): number {
  return Math.max(
    0,
    toNumber(getFieldValue(model, "current_interval_total_count", "currentIntervalTotalCount"), 0)
  );
}

function getMiniMaxWeeklyTotal(model: JsonRecord): number {
  return Math.max(
    0,
    toNumber(getFieldValue(model, "current_weekly_total_count", "currentWeeklyTotalCount"), 0)
  );
}

function pickMiniMaxRepresentativeModel(
  models: JsonRecord[],
  getTotal: (model: JsonRecord) => number
): JsonRecord | null {
  const withQuota = models.filter((model) => getTotal(model) > 0);
  const pool = withQuota.length > 0 ? withQuota : models;
  if (pool.length === 0) return null;

  return pool.reduce((best, current) => (getTotal(current) > getTotal(best) ? current : best));
}

function createMiniMaxQuotaFromCount(
  total: number,
  count: number,
  resetAt: string | null,
  countMeansRemaining: boolean
): UsageQuota {
  const used = countMeansRemaining ? Math.max(total - count, 0) : count;
  return createQuotaFromUsage(used, total, resetAt);
}

/**
 * MiniMax Coding Plan exposes per-window remaining as a 0–100 percent
 * (`current_interval_remaining_percent` / `current_weekly_remaining_percent`)
 * with zero request counts. Read it defensively (string-encoded numbers ok).
 */
function getMiniMaxRemainingPercent(
  model: JsonRecord,
  snakeKey: string,
  camelKey: string
): number | null {
  const raw = getFieldValue(model, snakeKey, camelKey);
  if (raw === null || raw === undefined || raw === "") return null;
  const parsed = toNumber(raw, NaN);
  return Number.isFinite(parsed) ? Math.max(0, Math.min(100, parsed)) : null;
}

/** Build a 0–100 percent-based window quota (used = 100 − remaining). */
function createMiniMaxQuotaFromPercent(
  remainingPercent: number,
  resetAt: string | null
): UsageQuota {
  const clamped = Math.max(0, Math.min(100, remainingPercent));
  return createQuotaFromUsage(100 - clamped, 100, resetAt);
}

/**
 * Build one MiniMax usage window (session or weekly) from the representative
 * model. Token Plan keys report request counts (`*_total_count`); Coding Plan
 * keys report zero counts and a `*_remaining_percent` instead — fall back to
 * that so the Coding Plan still surfaces a quota. The percent signal is keyed
 * off "counts == 0 + percent present", NOT the endpoint URL, because the
 * `token_plan/remains` and `coding_plan/remains` endpoints return identical
 * Coding-Plan payloads for a Coding Plan key.
 */
function buildMiniMaxWindow(
  models: JsonRecord[],
  getTotal: (model: JsonRecord) => number,
  usageCountKeys: [string, string],
  percentKeys: [string, string],
  resetKeys: [string, string, string, string],
  capturedAtMs: number,
  countMeansRemaining: boolean
): UsageQuota | null {
  const model = pickMiniMaxRepresentativeModel(models, getTotal);
  if (!model) return null;

  const resetAt = getMiniMaxQuotaResetAt(model, capturedAtMs, ...resetKeys);
  const total = getTotal(model);

  if (total > 0) {
    const count = Math.max(0, toNumber(getFieldValue(model, ...usageCountKeys), 0));
    return createMiniMaxQuotaFromCount(total, count, resetAt, countMeansRemaining);
  }

  const remainingPercent = getMiniMaxRemainingPercent(model, ...percentKeys);
  return remainingPercent !== null
    ? createMiniMaxQuotaFromPercent(remainingPercent, resetAt)
    : null;
}

function getMiniMaxAuthErrorMessage(message: string): string {
  const normalized = message.toLowerCase();
  if (
    normalized.includes("token plan") ||
    normalized.includes("coding plan") ||
    normalized.includes("active period") ||
    normalized.includes("invalid api key") ||
    normalized.includes("invalid key") ||
    normalized.includes("subscription")
  ) {
    return "MiniMax Token Plan API key invalid or inactive. Use an active Token Plan key.";
  }

  return "MiniMax access denied. Confirm the key is an active Token Plan API key.";
}

function getMiniMaxErrorSummary(status: number, message: string): string {
  const compact = message.replace(/\s+/g, " ").trim();
  if (!compact) {
    return `MiniMax usage endpoint error (${status}).`;
  }
  if (compact.length <= 160) {
    return `MiniMax usage endpoint error (${status}): ${compact}`;
  }
  return `MiniMax usage endpoint error (${status}): ${compact.slice(0, 157)}...`;
}

async function getMiniMaxUsage(apiKey: string, provider: "minimax" | "minimax-cn") {
  if (!apiKey) {
    return { message: "MiniMax API key not available. Add a Token Plan API key." };
  }

  const usageUrls = MINIMAX_USAGE_CONFIG[provider].usageUrls;
  let lastErrorMessage = "";

  for (let index = 0; index < usageUrls.length; index += 1) {
    const usageUrl = usageUrls[index];
    const canFallback = index < usageUrls.length - 1;

    try {
      const response = await fetch(usageUrl, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${apiKey}`,
          Accept: "application/json",
          "Content-Type": "application/json",
        },
      });

      const rawText = await response.text();
      let payload: JsonRecord = {};
      if (rawText) {
        try {
          payload = toRecord(JSON.parse(rawText));
        } catch {
          payload = {};
        }
      }

      const baseResp = toRecord(getFieldValue(payload, "base_resp", "baseResp"));
      const apiStatusCode = toNumber(getFieldValue(baseResp, "status_code", "statusCode"), 0);
      const apiStatusMessage = String(
        getFieldValue(baseResp, "status_msg", "statusMsg") ?? ""
      ).trim();
      const combinedMessage = `${apiStatusMessage} ${rawText}`.trim();
      const authLikeStatusMessage =
        /token plan|coding plan|invalid api key|invalid key|unauthorized|inactive/i;

      if (
        response.status === 401 ||
        response.status === 403 ||
        apiStatusCode === 1004 ||
        authLikeStatusMessage.test(apiStatusMessage)
      ) {
        return { message: getMiniMaxAuthErrorMessage(apiStatusMessage || combinedMessage) };
      }

      if (!response.ok) {
        lastErrorMessage = getMiniMaxErrorSummary(response.status, combinedMessage);
        if (
          (response.status === 404 || response.status === 405 || response.status >= 500) &&
          canFallback
        ) {
          continue;
        }
        return { message: `MiniMax connected. ${lastErrorMessage}` };
      }

      if (rawText && Object.keys(payload).length === 0) {
        return { message: "MiniMax connected. Unable to parse usage response." };
      }

      if (apiStatusCode !== 0) {
        if (apiStatusMessage) {
          return { message: `MiniMax connected. ${apiStatusMessage}` };
        }
        return { message: "MiniMax connected. Upstream quota API returned an error." };
      }

      const capturedAtMs = Date.now();
      const modelRemains = getFieldValue(payload, "model_remains", "modelRemains");
      const allModels = Array.isArray(modelRemains)
        ? modelRemains.map((item) => toRecord(item))
        : [];
      const textModels = allModels.filter((model) => {
        const modelName = String(getFieldValue(model, "model_name", "modelName") ?? "");
        return isMiniMaxTextQuotaModel(modelName);
      });

      if (textModels.length === 0) {
        return { message: "MiniMax connected. No text quota data was returned." };
      }

      const countMeansRemaining = usageUrl.includes("/coding_plan/remains");
      const quotas: Record<string, UsageQuota> = {};

      const sessionQuota = buildMiniMaxWindow(
        textModels,
        getMiniMaxSessionTotal,
        ["current_interval_usage_count", "currentIntervalUsageCount"],
        ["current_interval_remaining_percent", "currentIntervalRemainingPercent"],
        ["remains_time", "remainsTime", "end_time", "endTime"],
        capturedAtMs,
        countMeansRemaining
      );
      if (sessionQuota) {
        quotas["session (5h)"] = sessionQuota;
      }

      const weeklyQuota = buildMiniMaxWindow(
        textModels,
        getMiniMaxWeeklyTotal,
        ["current_weekly_usage_count", "currentWeeklyUsageCount"],
        ["current_weekly_remaining_percent", "currentWeeklyRemainingPercent"],
        ["weekly_remains_time", "weeklyRemainsTime", "weekly_end_time", "weeklyEndTime"],
        capturedAtMs,
        countMeansRemaining
      );
      if (weeklyQuota) {
        quotas["weekly (7d)"] = weeklyQuota;
      }

      if (Object.keys(quotas).length === 0) {
        return { message: "MiniMax connected. Unable to extract text quota usage." };
      }

      return { plan: getMiniMaxPlanLabel(payload, textModels), quotas };
    } catch (error) {
      lastErrorMessage = (error as Error).message;
      if (!canFallback) {
        break;
      }
    }
  }

  return {
    message: lastErrorMessage
      ? `MiniMax connected. Unable to fetch usage: ${lastErrorMessage}`
      : "MiniMax connected. Unable to fetch usage.",
  };
}

// CrofAI surfaces a tiny endpoint with two signals:
//   GET https://crof.ai/usage_api/  →  { usable_requests: number|null, credits: number }
// `usable_requests` is the daily request bucket on a subscription plan; `null`
// for pay-as-you-go. `credits` is the USD credit balance. We surface both as
// quotas so the Limits & Quotas page can render whichever the account uses.
async function getCrofUsage(apiKey: string) {
  if (!apiKey) {
    return { message: "CrofAI API key not available. Add a key to view usage." };
  }

  let response: Response;
  try {
    response = await fetch(CROF_USAGE_URL, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${apiKey}`,
        Accept: "application/json",
      },
    });
  } catch (error) {
    return { message: `CrofAI connected. Unable to fetch usage: ${(error as Error).message}` };
  }

  const rawText = await response.text();

  if (response.status === 401 || response.status === 403) {
    return { message: "CrofAI connected. The API key was rejected by /usage_api/." };
  }

  if (!response.ok) {
    return { message: `CrofAI connected. /usage_api/ returned HTTP ${response.status}.` };
  }

  let payload: JsonRecord = {};
  if (rawText) {
    try {
      payload = toRecord(JSON.parse(rawText));
    } catch {
      return { message: "CrofAI connected. Unable to parse /usage_api/ response." };
    }
  }

  const usableRequestsRaw = payload["usable_requests"];
  const usableRequests =
    usableRequestsRaw === null || usableRequestsRaw === undefined
      ? null
      : toNumber(usableRequestsRaw, 0);
  const credits = toNumber(payload["credits"], 0);

  const quotas: Record<string, UsageQuota> = {};

  if (usableRequests !== null) {
    // CrofAI's /usage_api/ returns only the remaining count; the daily
    // allotment is not exposed. CrofAI Pro plan = 1,000 requests/day per
    // their pricing page, so use that as the baseline total. If the user
    // is on a plan with a higher cap we widen the total to whatever they
    // currently report so we never compute a negative `used`.
    // Without this, total=0 makes the dashboard's percentage formula read
    // 0% (interpreted as "depleted" → red) even on a fresh bucket.
    const CROF_DAILY_BASELINE = 1000;
    const remaining = Math.max(0, usableRequests);
    const total = Math.max(CROF_DAILY_BASELINE, remaining);
    const used = Math.max(0, total - remaining);

    // CrofAI also does not return a reset timestamp and the docs only say
    // "requests left today". The Crof.ai dashboard shows the daily bucket
    // resetting at ~05:00 UTC (verified against the live countdown on
    // 2026-04-25), so synthesize the next 05:00 UTC instant to match.
    // Swap for a real field if Crof ever exposes one.
    const now = new Date();
    const RESET_HOUR_UTC = 5;
    const todayResetMs = Date.UTC(
      now.getUTCFullYear(),
      now.getUTCMonth(),
      now.getUTCDate(),
      RESET_HOUR_UTC
    );
    const nextResetMs =
      todayResetMs > now.getTime() ? todayResetMs : todayResetMs + 24 * 60 * 60 * 1000;
    const nextResetIso = new Date(nextResetMs).toISOString();

    quotas["Requests Today"] = {
      used,
      total,
      remaining,
      resetAt: nextResetIso,
      unlimited: false,
      displayName: `Requests Today: ${remaining} left`,
    };
  }

  // Credits are an open balance — render as unlimited so the UI shows the
  // dollar value rather than a misleading 0/0 bar.
  quotas["Credits"] = {
    used: 0,
    total: 0,
    remaining: 0,
    resetAt: null,
    unlimited: true,
    displayName: `Credits: $${credits.toFixed(4)}`,
  };

  return { quotas };
}

const GLM_QUOTA_ORDER = ["5 Hours Quota", "Weekly Quota", "Monthly Tools", "Tokens", "Time Limit"];

function getGlmQuotaLabel(type: unknown, unit: unknown): string | null {
  const normalized = typeof type === "string" ? type.trim().toUpperCase() : "";
  const unitValue = toNumber(unit, -1);

  switch (normalized) {
    case "TOKENS_LIMIT":
    case "TOKEN_LIMIT":
      if (unitValue === 3) return "5 Hours Quota";
      if (unitValue === 6) return "Weekly Quota";
      return "Tokens";
    case "TIME_LIMIT":
    case "TIME_USAGE_LIMIT":
      if (unitValue === 5) return "Monthly Tools";
      return "Time Limit";
    default:
      return null;
  }
}

function orderGlmQuotas(quotas: Record<string, UsageQuota>): Record<string, UsageQuota> {
  const ordered: Record<string, UsageQuota> = {};

  for (const key of GLM_QUOTA_ORDER) {
    if (quotas[key]) ordered[key] = quotas[key];
  }

  for (const [key, quota] of Object.entries(quotas)) {
    if (!ordered[key]) ordered[key] = quota;
  }

  return ordered;
}

async function getGlmUsage(apiKey: string, providerSpecificData?: Record<string, unknown>) {
  if (!apiKey) {
    return { message: "API key not available. Add a coding plan API key to view usage." };
  }

  const quotaUrl = getGlmQuotaUrl(providerSpecificData);

  const res = await fetch(quotaUrl, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      Accept: "application/json",
    },
  });

  if (!res.ok) {
    if (res.status === 401) throw new Error("Invalid API key");
    throw new Error(`GLM quota API error (${res.status})`);
  }

  const json = await res.json();
  if (toNumber(json.code, 200) === 401 || json.success === false) {
    throw new Error("Invalid API key");
  }

  const data = toRecord(json.data);
  const limits: unknown[] = Array.isArray(data.limits) ? data.limits : [];
  const quotas: Record<string, UsageQuota> = {};

  for (const limit of limits) {
    const src = toRecord(limit);
    const type = String(src.type || "").toUpperCase();
    const resetMs = toNumber(src.nextResetTime, 0);
    const resetAt = resetMs > 0 ? new Date(resetMs).toISOString() : null;

    if (type === "TOKENS_LIMIT") {
      const quotaName = getGlmTokenQuotaName(src, quotas);
      const usedPercent = toPercentage(src.percentage);
      const remaining = Math.max(0, 100 - usedPercent);

      quotas[quotaName] = {
        used: usedPercent,
        total: 100,
        remaining,
        remainingPercentage: remaining,
        resetAt,
        displayName: getGlmQuotaDisplayName(quotaName),
        details: Array.isArray(src.models)
          ? (src.models as unknown[]).map((m) => {
              const modelInfo = toRecord(m);
              return {
                name: String(modelInfo.model || ""),
                used: toNumber(modelInfo.percentage, 0),
              };
            })
          : [],
        unlimited: false,
      };
      continue;
    }

    if (type === "TIME_LIMIT") {
      const total = toNumber(src.usage, toNumber(src.total, 0));
      const remaining = toNumber(src.remaining, Math.max(0, 100 - toPercentage(src.percentage)));
      const used = toNumber(src.currentValue, Math.max(0, total - remaining));
      const remainingPercentage =
        total > 0 ? Math.max(0, Math.min(100, Math.round((remaining / total) * 100))) : 0;

      quotas["mcp_monthly"] = {
        used,
        total,
        remaining,
        remainingPercentage,
        resetAt,
        unlimited: false,
        displayName: "Monthly",
        details: Array.isArray(src.usageDetails)
          ? src.usageDetails.map((item) => {
              const detail = toRecord(item);
              return {
                name: String(detail.modelCode || detail.name || "usage"),
                used: toNumber(detail.usage, 0),
              };
            })
          : undefined,
      };
    }
  }

  const levelRaw =
    typeof data.planName === "string"
      ? data.planName
      : typeof data.level === "string"
        ? data.level
        : "";
  const plan = levelRaw ? toTitleCase(levelRaw.replace(/\s*plan$/i, "")) : null;

  return { plan, quotas: orderGlmQuotas(quotas) };
}

async function getOpenCodeGoUsage(apiKey: string) {
  const token = normalizeOpenCodeGoQuotaToken(apiKey);

  if (!token) {
    return { message: "API key not available. Add an OpenCode Go API key to view usage." };
  }

  const res = await fetch(OPENCODE_GO_QUOTA_URL, {
    headers: {
      Authorization: token,
      "Accept-Language": "en-US,en",
      "Content-Type": "application/json",
      Accept: "application/json",
    },
  });

  if (!res.ok) {
    if (res.status === 401 || res.status === 403) throw new Error("Invalid OpenCode Go API key");
    throw new Error(`OpenCode Go quota API error (${res.status})`);
  }

  const json = await res.json();
  const code = toNumber(json.code, 200);
  if (code === 401 || code === 403 || json.success === false) {
    throw new Error("Invalid OpenCode Go API key");
  }

  const data = toRecord(json.data);
  const limits: unknown[] = Array.isArray(data.limits) ? data.limits : [];
  const quotas: Record<string, UsageQuota> = {};

  for (const limit of limits) {
    const src = toRecord(limit);
    const type = String(src.type || "").toUpperCase();
    const resetAt = parseResetTime(src.nextResetTime);

    if (type === "TOKENS_LIMIT" || type === "TOKEN_LIMIT") {
      const quotaName = getOpenCodeGoTokenQuotaName(src, quotas);

      quotas[quotaName] = buildOpenCodeGoDollarQuota(
        quotaName,
        src.percentage,
        resetAt,
        undefined,
        Array.isArray(src.models)
          ? (src.models as unknown[]).map((model) => {
              const modelInfo = toRecord(model);
              return {
                name: String(modelInfo.model || modelInfo.modelCode || "usage"),
                used: toNumber(modelInfo.percentage, 0),
              };
            })
          : undefined
      );
      continue;
    }

    if (type === "TIME_LIMIT" || type === "TIME_USAGE_LIMIT") {
      quotas.mcp_monthly = buildOpenCodeGoDollarQuota(
        "mcp_monthly",
        src.percentage,
        resetAt,
        src.currentValue,
        Array.isArray(src.usageDetails)
          ? src.usageDetails.map((item) => {
              const detail = toRecord(item);
              return {
                name: String(detail.modelCode || detail.name || "usage"),
                used: toNumber(detail.usage, 0),
              };
            })
          : undefined
      );
    }
  }

  const levelRaw =
    typeof data.planName === "string"
      ? data.planName
      : typeof data.level === "string"
        ? data.level
        : "";
  const planLabel = toTitleCase(levelRaw.replace(/\s*plan$/i, ""));
  const plan = planLabel
    ? /^opencode\s+go\b/i.test(planLabel)
      ? planLabel
      : `OpenCode Go ${planLabel}`
    : null;

  return { plan, quotas: orderOpenCodeGoQuotas(quotas) };
}

/**
 * Bailian (Alibaba Coding Plan) Usage
 * Fetches triple-window quota (5h, weekly, monthly) and returns worst-case.
 */
async function getBailianCodingPlanUsage(
  connectionId: string,
  apiKey: string,
  providerSpecificData?: Record<string, unknown>
) {
  try {
    const connection = { apiKey, providerSpecificData };
    const quota = await fetchBailianQuota(connectionId, connection);

    if (!quota) {
      return { message: "Bailian Coding Plan connected. Unable to fetch quota." };
    }

    const bailianQuota = quota as BailianTripleWindowQuota;
    const used = bailianQuota.used;
    const total = bailianQuota.total;
    const remaining = Math.max(0, total - used);
    const remainingPercentage = Math.round(remaining);

    return {
      plan: "Alibaba Coding Plan",
      used,
      total,
      remaining,
      remainingPercentage,
      resetAt: bailianQuota.resetAt,
      unlimited: false,
      displayName: "Alibaba Coding Plan",
    };
  } catch (error) {
    return { message: `Bailian Coding Plan error: ${(error as Error).message}` };
  }
}

/**
 * DeepSeek Usage
 * Fetches balance from the DeepSeek balance API.
 * Returns all balances (USD and CNY) as "credits" for credits-style UI display.
 */
async function getDeepseekUsage(connectionId: string, apiKey: string) {
  try {
    const connection = { apiKey };
    const quota = await fetchDeepseekQuota(connectionId, connection);

    if (!quota) {
      return { message: "DeepSeek API key not available. Add a key to view usage." };
    }

    const deepseekQuota = quota as DeepseekQuota;
    const { balances, isAvailable, limitReached } = deepseekQuota;

    const quotas: Record<string, UsageQuota> = {};

    // Show all balances as credits-style entries (e.g., credits_usd, credits_cny)
    // The UI will display them as "🪙 Balance (USD) $50.00"
    for (const balanceInfo of balances) {
      const key = `credits_${balanceInfo.currency.toLowerCase()}`;
      quotas[key] = {
        used: 0,
        total: 0,
        remaining: balanceInfo.balance,
        remainingPercentage: 100,
        resetAt: null,
        unlimited: true,
        currency: balanceInfo.currency,
        grantedBalance: balanceInfo.grantedBalance,
        toppedUpBalance: balanceInfo.toppedUpBalance,
      };
    }

    const plan = isAvailable ? "DeepSeek" : "DeepSeek (Insufficient Balance)";

    return {
      plan,
      quotas,
      isAvailable,
      limitReached,
    };
  } catch (error) {
    return { message: `DeepSeek error: ${(error as Error).message}` };
  }
}

// Xiaomi MiMo Token Plan monthly limit (tokens). Keep in sync with the
// "xiaomi-mimo" preset in src/lib/quota/planRegistry.ts.
const XIAOMI_MIMO_MONTHLY_TOKEN_LIMIT = 4_100_000_000;

/**
 * Xiaomi MiMo — SELF-TRACKED monthly quota.
 *
 * Xiaomi exposes plan usage only behind the console session cookie (the API key
 * cannot reach the `tokenPlan/usage` endpoint), so there is no upstream usage
 * API to call. Instead we count the tokens OmniRoute itself routed to this
 * connection in the current UTC month (from `usage_history`) and compare them
 * to the known Token Plan monthly limit. This reflects only traffic that went
 * through OmniRoute, not the provider's own dashboard figure.
 */
async function getXiaomiMimoUsage(connectionId: string) {
  if (!connectionId) {
    return { message: "Xiaomi MiMo: connection id unavailable for self-tracked quota." };
  }
  try {
    const { getMonthlyProviderTokensForConnection } = await import("@/lib/usage/usageStats");
    const used = getMonthlyProviderTokensForConnection("xiaomi-mimo", connectionId);
    const total = XIAOMI_MIMO_MONTHLY_TOKEN_LIMIT;
    const now = new Date();
    const resetAt = new Date(
      Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)
    ).toISOString();
    return {
      plan: "Xiaomi MiMo Token Plan (OmniRoute-tracked)",
      quotas: {
        monthly: createQuotaFromUsage(used, total, resetAt),
      },
    };
  } catch (error) {
    return { message: `Xiaomi MiMo self-tracked usage error: ${(error as Error).message}` };
  }
}

/**
 * OpenCode Go / OpenCode / OpenCode Zen Usage
 * Delegates to the dedicated opencodeQuotaFetcher and shapes the result into
 * the standard `{ plan, quotas }` usage response expected by the limits page.
 *
 * Three rolling windows are surfaced: $12/5h, $30/wk, $60/mo.
 */
async function getOpencodeUsage(connectionId: string, apiKey: string) {
  if (!apiKey) {
    return { message: "OpenCode API key not available. Add a key to view usage." };
  }

  try {
    const quota = (await fetchOpencodeQuota(connectionId, { apiKey })) as OpencodeTripleWindowQuota | null;

    if (!quota) {
      return { message: "OpenCode connected. Unable to fetch quota data." };
    }

    const { window5h, windowWeekly, windowMonthly, limitReached } = quota;

    const quotas: Record<string, UsageQuota> = {};

    // $12 / 5-hour rolling window
    quotas["window_5h"] = {
      used: window5h.percentUsed * 12,
      total: 12,
      remaining: (1 - window5h.percentUsed) * 12,
      remainingPercentage: (1 - window5h.percentUsed) * 100,
      resetAt: window5h.resetAt,
      unlimited: false,
      displayName: "$12 / 5-hour",
      currency: "USD",
    };

    // $30 / weekly window
    quotas["window_weekly"] = {
      used: windowWeekly.percentUsed * 30,
      total: 30,
      remaining: (1 - windowWeekly.percentUsed) * 30,
      remainingPercentage: (1 - windowWeekly.percentUsed) * 100,
      resetAt: windowWeekly.resetAt,
      unlimited: false,
      displayName: "$30 / week",
      currency: "USD",
    };

    // $60 / monthly window
    quotas["window_monthly"] = {
      used: windowMonthly.percentUsed * 60,
      total: 60,
      remaining: (1 - windowMonthly.percentUsed) * 60,
      remainingPercentage: (1 - windowMonthly.percentUsed) * 100,
      resetAt: windowMonthly.resetAt,
      unlimited: false,
      displayName: "$60 / month",
      currency: "USD",
    };

    return {
      plan: "OpenCode Go",
      quotas,
      limitReached,
    };
  } catch (error) {
    return { message: `OpenCode error: ${sanitizeErrorMessage(error)}` };
  }
}

/**
 * NanoGPT Usage
 * Fetches subscription-level quota from the NanoGPT API.
 * Returns daily/weekly token limits and daily image limits for PRO accounts.
 */
async function getNanoGptUsage(apiKey: string) {
  if (!apiKey) {
    return { message: "NanoGPT API key not available. Add a key to view usage." };
  }

  try {
    const res = await fetch(NANOGPT_CONFIG.usageUrl, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    if (!res.ok) {
      if (res.status === 401) return { message: "Invalid NanoGPT API key." };
      return { message: `NanoGPT quota API error (${res.status})` };
    }

    const data = toRecord(await res.json());
    const quotas: Record<string, UsageQuota> = {};

    // active -> PRO, otherwise FREE
    const plan = data.active ? "PRO" : "FREE";

    if (data.active) {
      // 1. Tokens limit
      // dailyInputTokens if exists, else weeklyInputTokens
      let tokenQuota = toRecord(data.dailyInputTokens);
      let tokenLabel = "Daily Tokens";
      if (!tokenQuota.resetAt) {
        const weeklyQuota = toRecord(data.weeklyInputTokens);
        if (weeklyQuota.remaining !== undefined) {
          tokenQuota = weeklyQuota;
          tokenLabel = "Weekly Tokens";
        }
      }

      if (tokenQuota.remaining !== undefined) {
        const used = toNumber(tokenQuota.used, 0);
        const remaining = toNumber(tokenQuota.remaining, 0);
        const total = used + remaining;
        quotas[tokenLabel] = {
          used,
          total,
          remaining,
          remainingPercentage: clampPercentage(100 - toNumber(tokenQuota.percentUsed, 0) * 100),
          resetAt: parseResetTime(tokenQuota.resetAt),
          unlimited: false,
        };
      }

      // 2. Images limit
      const imageQuota = toRecord(data.dailyImages);
      if (imageQuota.remaining !== undefined) {
        const used = toNumber(imageQuota.used, 0);
        const remaining = toNumber(imageQuota.remaining, 0);
        const total = used + remaining;
        quotas["Daily Images"] = {
          used,
          total,
          remaining,
          remainingPercentage: clampPercentage(100 - toNumber(imageQuota.percentUsed, 0) * 100),
          resetAt: parseResetTime(imageQuota.resetAt),
          unlimited: false,
        };
      }

      if (Object.keys(quotas).length === 0) {
        return { plan, message: "NanoGPT connected, but no active limits found." };
      }
    }

    return { plan, quotas };
  } catch (error) {
    return { message: `NanoGPT connected. Unable to fetch usage: ${(error as Error).message}` };
  }
}

/**
 * Decode the `sub` claim of a Cursor JWT (the WorkOS user id).
 * Returns null if the token is not a parseable JWT.
 */
function decodeCursorJwtSub(token: string): string | null {
  if (!token || typeof token !== "string") return null;
  const parts = token.split(".");
  if (parts.length !== 3) return null;
  try {
    let payload = parts[1].replace(/-/g, "+").replace(/_/g, "/");
    while (payload.length % 4 !== 0) payload += "=";
    const decoded = JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
    const sub = decoded?.sub;
    return typeof sub === "string" && sub.length > 0 ? sub : null;
  } catch {
    return null;
  }
}

/**
 * Cursor Pro Plan Usage
 * Fetches current-billing-cycle spend from the cursor.com dashboard API and exposes three
 * windows that mirror the cursor.com/dashboard/spending UI: Total / Auto + Composer / API.
 */
async function getCursorUsage(accessToken: string, providerSpecificData?: unknown) {
  if (!accessToken) {
    return { message: "Cursor access token missing. Re-import the connection from Cursor IDE." };
  }

  const storedUserId = (() => {
    const raw = toRecord(providerSpecificData).userId;
    return typeof raw === "string" && raw.length > 0 ? raw : null;
  })();
  const userId = storedUserId || decodeCursorJwtSub(accessToken);

  if (!userId) {
    return {
      message: "Cursor token missing user id. Re-import the connection from Cursor IDE.",
    };
  }

  try {
    const response = await fetch(CURSOR_USAGE_CONFIG.usageUrl, {
      method: "POST",
      redirect: "manual",
      headers: {
        Cookie: `WorkosCursorSessionToken=${userId}::${accessToken}`,
        Origin: CURSOR_USAGE_CONFIG.origin,
        Referer: CURSOR_USAGE_CONFIG.referer,
        "Content-Type": "application/json",
        Accept: "application/json",
        "User-Agent": CURSOR_USAGE_CONFIG.userAgent,
      },
      body: "{}",
    });

    // 3xx redirect to WorkOS authkit means the session cookie was rejected.
    if (response.status >= 300 && response.status < 400) {
      return {
        plan: "Cursor",
        message: "Cursor session expired. Re-import the token from Cursor IDE.",
      };
    }

    if (!response.ok) {
      const errorText = (await response.text()).slice(0, 200);
      if (response.status === 401 || response.status === 403) {
        return {
          plan: "Cursor",
          message: "Cursor session unauthorized. Re-import the token from Cursor IDE.",
        };
      }
      return {
        plan: "Cursor",
        message: `Cursor usage endpoint error (${response.status}): ${errorText}`,
      };
    }

    const data = toRecord(await response.json());
    const planUsage = toRecord(data.planUsage);

    if (Object.keys(planUsage).length === 0) {
      return {
        plan: "Cursor",
        message: "Cursor connected. No active plan usage returned.",
      };
    }

    const limitCents = Math.max(0, toNumber(planUsage.limit, 0));
    const totalSpendCents = Math.max(0, toNumber(planUsage.totalSpend, 0));
    const autoPercentUsed = clampPercentage(toNumber(planUsage.autoPercentUsed, 0));
    const apiPercentUsed = clampPercentage(toNumber(planUsage.apiPercentUsed, 0));
    const totalPercentUsed = clampPercentage(toNumber(planUsage.totalPercentUsed, 0));

    // billingCycleEnd is a numeric-string in ms; coerce so parseResetTime sees a number.
    const billingCycleEndMs = toNumber(data.billingCycleEnd, 0);
    const resetAt = billingCycleEndMs > 0 ? parseResetTime(billingCycleEndMs) : null;

    // Convert cents → dollars rounded to 2 decimal places.
    const toDollars = (cents: number) => Math.round(cents) / 100;

    const limitDollars = toDollars(limitCents);
    const buildWindow = (percentUsed: number, usedCentsOverride?: number): UsageQuota => {
      const usedCents =
        typeof usedCentsOverride === "number"
          ? usedCentsOverride
          : Math.round((limitCents * percentUsed) / 100);
      const used = toDollars(Math.min(usedCents, limitCents));
      const remaining = toDollars(Math.max(limitCents - Math.min(usedCents, limitCents), 0));
      return {
        used,
        total: limitDollars,
        remaining,
        remainingPercentage: clampPercentage(100 - percentUsed),
        resetAt,
        unlimited: false,
      };
    };

    const quotas: Record<string, UsageQuota> = {
      Total: buildWindow(totalPercentUsed, totalSpendCents),
      "Auto + Composer": buildWindow(autoPercentUsed),
      API: buildWindow(apiPercentUsed),
    };

    return {
      plan: "Cursor Pro",
      quotas,
    };
  } catch (error) {
    return {
      plan: "Cursor",
      message: `Cursor connected. Unable to fetch usage: ${(error as Error).message}`,
    };
  }
}

/**
 * Single source of truth for which providers have a `getUsageForProvider`
 * implementation. Consumers like `genericQuotaFetcher.ts` reference this so
 * the registration list can't drift from the switch statement below.
 *
 * If you add a new provider to the switch, add it here too.
 */
export const USAGE_FETCHER_PROVIDERS = [
  "github",
  "gemini-cli",
  "antigravity",
  "agy",
  "claude",
  "codex",
  "cursor",
  "kiro",
  "amazon-q",
  "kimi-coding",
  "qwen",
  "qoder",
  "glm",
  "glm-cn",
  "zai",
  "glmt",
  "opencode-go",
  "minimax",
  "minimax-cn",
  "crof",
  "bailian-coding-plan",
  "nanogpt",
  "deepseek",
  "opencode",
  "opencode-zen",
  "xiaomi-mimo",
] as const;

export type UsageFetcherProvider = (typeof USAGE_FETCHER_PROVIDERS)[number];

/**
 * Get usage data for a provider connection
 * @param {Object} connection - Provider connection with accessToken
 * @returns {Promise<unknown>} Usage data with quotas
 */
export async function getUsageForProvider(
  connection: UsageProviderConnection,
  options: { forceRefresh?: boolean } = {}
) {
  const { id, provider, accessToken, apiKey, providerSpecificData, projectId, email } = connection;

  switch (provider) {
    case "github":
      return await getGitHubUsage(accessToken, providerSpecificData);
    case "gemini-cli":
      return await getGeminiUsage(accessToken, providerSpecificData, projectId);
    case "antigravity":
    case "agy":
      return await getAntigravityUsage(accessToken, providerSpecificData, projectId, id, options);
    case "claude":
      return await getClaudeUsage(accessToken);
    case "codex":
      return await getCodexUsage(accessToken, providerSpecificData);
    case "cursor":
      return await getCursorUsage(accessToken || "", providerSpecificData);
    case "kiro":
    case "amazon-q":
      return await getKiroUsage(accessToken, providerSpecificData);
    case "kimi-coding":
      return await getKimiUsage(accessToken);
    case "qwen":
      return await getQwenUsage(accessToken, providerSpecificData);
    case "qoder":
      return await getQoderUsage(accessToken);
    case "glm":
    case "glm-cn":
    case "zai":
    case "glmt":
      return await getGlmUsage(apiKey || "", {
        ...(providerSpecificData || {}),
        ...(provider === "glm-cn" ? { apiRegion: "china" } : {}),
      });
    case "opencode-go":
      return await getOpenCodeGoUsage(apiKey || "");
    case "minimax":
    case "minimax-cn":
      return await getMiniMaxUsage(apiKey || "", provider);
    case "crof":
      return await getCrofUsage(apiKey || "");
    case "bailian-coding-plan":
      return await getBailianCodingPlanUsage(id || "", apiKey || "", providerSpecificData);
    case "nanogpt":
      return await getNanoGptUsage(apiKey || "");
    case "deepseek":
      return await getDeepseekUsage(id || "", apiKey || "");
    case "opencode":
    case "opencode-zen":
      return await getOpencodeUsage(id || "", apiKey || "");
    case "xiaomi-mimo":
      return await getXiaomiMimoUsage(id || "");
    default:
      return { message: `Usage API not implemented for ${provider}` };
  }
}

/**
 * Parse reset date/time to ISO string
 * Handles multiple formats: Unix timestamp (ms), ISO date string, etc.
 */
function parseResetTime(resetValue: unknown): string | null {
  if (!resetValue) return null;

  try {
    let date: Date;
    if (resetValue instanceof Date) {
      date = resetValue;
    } else if (typeof resetValue === "number") {
      date = new Date(resetValue < 1e12 ? resetValue * 1000 : resetValue);
    } else if (typeof resetValue === "string") {
      date = new Date(resetValue);
    } else {
      return null;
    }

    // Epoch-zero (1970-01-01) means no scheduled reset — treat as null
    if (date.getTime() <= 0) return null;

    return date.toISOString();
  } catch (error) {
    return null;
  }
}

/**
 * GitHub Copilot Usage
 * Uses GitHub accessToken (not copilotToken) to call copilot_internal/user API
 */
async function getGitHubUsage(accessToken?: string, providerSpecificData?: JsonRecord) {
  try {
    if (!accessToken) {
      throw new Error("No GitHub access token available. Please re-authorize the connection.");
    }

    // copilot_internal/user API requires GitHub OAuth token, not copilotToken
    const response = await fetch("https://api.github.com/copilot_internal/user", {
      headers: getGitHubCopilotInternalUserHeaders(`token ${accessToken}`),
    });

    if (!response.ok) {
      const error = await response.text();
      if (response.status === 401 || response.status === 403) {
        return {
          message: `GitHub token expired or permission denied. Please re-authenticate the connection.`,
        };
      }
      throw new Error(`GitHub API error: ${error}`);
    }

    const data = await response.json();
    const dataRecord = toRecord(data);

    // Handle different response formats (paid vs free)
    if (dataRecord.quota_snapshots) {
      // Paid plan format
      const snapshots = toRecord(dataRecord.quota_snapshots);
      const resetAt = parseResetTime(
        getFieldValue(dataRecord, "quota_reset_date", "quotaResetDate")
      );
      const premiumQuota = formatGitHubQuotaSnapshot(snapshots.premium_interactions, resetAt);
      const chatQuota = formatGitHubQuotaSnapshot(snapshots.chat, resetAt);
      const completionsQuota = formatGitHubQuotaSnapshot(snapshots.completions, resetAt);
      const quotas: Record<string, UsageQuota> = {};

      if (shouldDisplayGitHubQuota(premiumQuota)) {
        quotas.premium_interactions = premiumQuota;
      }
      if (shouldDisplayGitHubQuota(chatQuota)) {
        quotas.chat = chatQuota;
      }
      if (shouldDisplayGitHubQuota(completionsQuota)) {
        quotas.completions = completionsQuota;
      }

      return {
        plan: inferGitHubPlanName(dataRecord, premiumQuota),
        resetDate: getFieldValue(dataRecord, "quota_reset_date", "quotaResetDate"),
        quotas,
      };
    } else if (dataRecord.monthly_quotas || dataRecord.limited_user_quotas) {
      // Free/limited plan format. NOTE (#2876): the upstream field
      // `limited_user_quotas[name]` is the *remaining* count for the month
      // (it counts down toward 0 and resets on `limited_user_reset_date`),
      // NOT the used count. The pre-3.8.6 implementation inverted this and
      // showed "0% when not used / 100% when fully used" on the dashboard.
      // Confirmed against three independent upstream parsers:
      //   - robinebers/openusage  docs/providers/copilot.md (Free Tier table)
      //   - raycast/extensions    agent-usage/src/copilot/fetcher.ts (inline comment)
      //   - looplj/axonhub        frontend/src/components/quota-badges.tsx
      const monthlyQuotas = toRecord(dataRecord.monthly_quotas);
      const remainingQuotas = toRecord(dataRecord.limited_user_quotas);
      const resetDate = getFieldValue(
        dataRecord,
        "limited_user_reset_date",
        "limitedUserResetDate"
      );
      const resetAt = parseResetTime(resetDate);
      const quotas: Record<string, UsageQuota> = {};

      const addLimitedQuota = (name: string) => {
        const total = toNumber(getFieldValue(monthlyQuotas, name, name), 0);
        if (total <= 0) return null;
        const remainingRaw = Math.max(
          0,
          toNumber(getFieldValue(remainingQuotas, name, name), 0)
        );
        const remaining = Math.min(remainingRaw, total);
        const used = Math.max(total - remaining, 0);
        quotas[name] = {
          used,
          total,
          remaining,
          remainingPercentage: clampPercentage((remaining / total) * 100),
          unlimited: false,
          resetAt,
        };
        return quotas[name];
      };

      const premiumQuota = addLimitedQuota("premium_interactions");
      addLimitedQuota("chat");
      addLimitedQuota("completions");

      return {
        plan: inferGitHubPlanName(dataRecord, premiumQuota),
        resetDate,
        quotas,
      };
    }

    return { message: "GitHub Copilot connected. Unable to parse quota data." };
  } catch (error) {
    throw new Error(`Failed to fetch GitHub usage: ${error.message}`);
  }
}

function formatGitHubQuotaSnapshot(
  quota: unknown,
  resetAt: string | null = null
): UsageQuota | null {
  const source = toRecord(quota);
  if (Object.keys(source).length === 0) return null;

  const unlimited = source.unlimited === true;
  const entitlement = toNumber(source.entitlement, Number.NaN);
  const totalValue = toNumber(source.total, Number.NaN);
  const remainingValue = toNumber(source.remaining, Number.NaN);
  const usedValue = toNumber(source.used, Number.NaN);
  const percentRemainingValue = toNumber(
    getFieldValue(source, "percent_remaining", "percentRemaining"),
    Number.NaN
  );

  let total = Number.isFinite(totalValue)
    ? Math.max(0, totalValue)
    : Number.isFinite(entitlement)
      ? Math.max(0, entitlement)
      : 0;
  let remaining = Number.isFinite(remainingValue) ? Math.max(0, remainingValue) : undefined;
  let used = Number.isFinite(usedValue) ? Math.max(0, usedValue) : undefined;
  let remainingPercentage = Number.isFinite(percentRemainingValue)
    ? clampPercentage(percentRemainingValue)
    : undefined;

  if (used === undefined && total > 0 && remaining !== undefined) {
    used = Math.max(total - remaining, 0);
  }

  if (remaining === undefined && total > 0 && used !== undefined) {
    remaining = Math.max(total - used, 0);
  }

  if (remainingPercentage === undefined && total > 0 && remaining !== undefined) {
    remainingPercentage = clampPercentage((remaining / total) * 100);
  }

  if (total <= 0 && remainingPercentage !== undefined) {
    total = 100;
    used = 100 - remainingPercentage;
    remaining = remainingPercentage;
  }

  return {
    used: Math.max(0, used ?? 0),
    total,
    remaining,
    remainingPercentage,
    resetAt,
    unlimited,
  };
}

function inferGitHubPlanName(data: JsonRecord, premiumQuota: UsageQuota | null): string {
  const rawPlan = getFieldValue(data, "copilot_plan", "copilotPlan");
  const rawSku = getFieldValue(data, "access_type_sku", "accessTypeSku");
  const planText = typeof rawPlan === "string" ? rawPlan.trim() : "";
  const skuText = typeof rawSku === "string" ? rawSku.trim() : "";
  const combined = `${skuText} ${planText}`.trim().toUpperCase();
  const monthlyQuotas = toRecord(getFieldValue(data, "monthly_quotas", "monthlyQuotas"));
  const premiumTotal =
    premiumQuota?.total ||
    toNumber(getFieldValue(monthlyQuotas, "premium_interactions", "premiumInteractions"), 0);
  const chatTotal = toNumber(getFieldValue(monthlyQuotas, "chat", "chat"), 0);

  if (combined.includes("PRO+") || combined.includes("PRO_PLUS") || combined.includes("PROPLUS")) {
    return "Copilot Pro+";
  }
  if (combined.includes("ENTERPRISE")) return "Copilot Enterprise";
  if (combined.includes("BUSINESS")) return "Copilot Business";
  if (combined.includes("STUDENT")) return "Copilot Student";
  if (combined.includes("FREE")) return "Copilot Free";
  if (combined.includes("PRO")) return "Copilot Pro";

  if (premiumTotal >= 1400) return "Copilot Pro+";
  if (premiumTotal >= 900) return "Copilot Enterprise";
  if (premiumTotal >= 250) {
    if (combined.includes("INDIVIDUAL")) return "Copilot Pro";
    return "Copilot Business";
  }
  if (premiumTotal > 0 || chatTotal === 50) return "Copilot Free";

  if (skuText) {
    const label = toDisplayLabel(skuText);
    return label ? `Copilot ${label}` : "GitHub Copilot";
  }
  if (planText) {
    const label = toDisplayLabel(planText);
    return label ? `Copilot ${label}` : "GitHub Copilot";
  }
  return "GitHub Copilot";
}

// ── Gemini CLI subscription info cache ──────────────────────────────────────
// Prevents duplicate loadCodeAssist calls within the same quota cycle.
// Key: accessToken → { data, fetchedAt }
const _geminiCliSubCache = new Map<string, SubscriptionCacheEntry>();
const GEMINI_CLI_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes

/**
 * Gemini CLI Usage — fetch per-model quota from Cloud Code Assist API.
 * Gemini CLI and Antigravity share the same upstream (cloudcode-pa.googleapis.com),
 * so this follows the same pattern as getAntigravityUsage().
 */
async function getGeminiUsage(
  accessToken?: string,
  providerSpecificData?: JsonRecord,
  connectionProjectId?: string
) {
  if (!accessToken) {
    return { plan: "Free", message: "Gemini CLI access token not available." };
  }

  try {
    const subscriptionInfo = await getGeminiCliSubscriptionInfoCached(accessToken);
    const projectId =
      connectionProjectId ||
      providerSpecificData?.projectId ||
      toRecord(subscriptionInfo).cloudaicompanionProject ||
      null;

    const plan = getGeminiCliPlanLabel(subscriptionInfo);

    if (!projectId) {
      return { plan, message: "Gemini CLI project ID not available." };
    }

    // Use retrieveUserQuota (same endpoint as Gemini CLI /stats command).
    // Returns per-model buckets with remainingFraction and resetTime.
    const response = await fetch(
      "https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota",
      {
        method: "POST",
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ project: projectId }),
        signal: AbortSignal.timeout(10000),
      }
    );

    if (!response.ok) {
      return { plan, message: `Gemini CLI quota error (${response.status}).` };
    }

    const data = await response.json();
    const quotas: Record<string, UsageQuota> = {};

    const dataRecord = toRecord(data);
    if (Array.isArray(dataRecord.buckets)) {
      for (const bucketValue of dataRecord.buckets) {
        const bucket = toRecord(bucketValue);
        if (!bucket.modelId || bucket.remainingFraction == null) continue;

        const remainingFraction = toNumber(bucket.remainingFraction, 0);
        const remainingPercentage = remainingFraction * 100;
        const QUOTA_NORMALIZED_BASE = 1000;
        const total = QUOTA_NORMALIZED_BASE;
        const remaining = Math.round(total * remainingFraction);
        const used = Math.max(0, total - remaining);

        quotas[String(bucket.modelId)] = {
          used,
          total,
          resetAt: parseResetTime(bucket.resetTime),
          remainingPercentage,
          unlimited: false,
        };
      }
    }

    return { plan, quotas };
  } catch (error) {
    return { message: `Gemini CLI error: ${(error as Error).message}` };
  }
}

/**
 * Get Gemini CLI subscription info (cached, 5 min TTL)
 */
async function getGeminiCliSubscriptionInfoCached(accessToken: string): Promise<unknown> {
  const cacheKey = accessToken;
  const cached = _geminiCliSubCache.get(cacheKey);

  if (cached && Date.now() - cached.fetchedAt < GEMINI_CLI_CACHE_TTL_MS) {
    return cached.data;
  }

  const data = await getGeminiCliSubscriptionInfo(accessToken);
  _geminiCliSubCache.set(cacheKey, { data, fetchedAt: Date.now() });
  return data;
}

/**
 * Get Gemini CLI subscription info using correct headers.
 */
async function getGeminiCliSubscriptionInfo(accessToken: string): Promise<unknown | null> {
  try {
    const response = await fetch(GEMINI_CLI_USAGE_URL, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        metadata: {
          ideType: "IDE_UNSPECIFIED",
          platform: "PLATFORM_UNSPECIFIED",
          pluginType: "GEMINI",
        },
      }),
    });

    if (!response.ok) return null;

    return await response.json();
  } catch {
    return null;
  }
}

/**
 * Map Gemini CLI subscription tier to display label (same tiers as Antigravity).
 */
function getGeminiCliPlanLabel(subscriptionInfo: unknown): string {
  return mapCodeAssistSubscriptionToPlanLabel(subscriptionInfo);
}

// ── Antigravity subscription info cache ──────────────────────────────────────
// Prevents duplicate loadCodeAssist calls within the same quota cycle.
// Key: truncated accessToken → { data, fetchedAt }
const _antigravitySubCache = new Map<string, SubscriptionCacheEntry>();
const ANTIGRAVITY_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
const ANTIGRAVITY_MODELS_CACHE_TTL_MS = 60 * 1000;
const ANTIGRAVITY_CREDIT_PROBE_TTL_MS = 5 * 60 * 1000;
const _antigravityAvailableModelsCache = new Map<string, { data: unknown; fetchedAt: number }>();
const _antigravityAvailableModelsInflight = new Map<string, Promise<unknown>>();
const _antigravityCreditProbeCache = new Map<string, { data: number | null; fetchedAt: number }>();
const _antigravityCreditProbeInflight = new Map<string, Promise<number | null>>();

// ── Proactive TTL purging for module-level caches ──────────────────────────
// All 4 data caches only evict on read (passive TTL). This interval proactively
// purges stale entries so keys accessed once and never again don't leak memory.
// The 2 inflight Maps (availableModelsInflight, creditProbeInflight) self-clean
// when the Promise resolves/rejects, so they are NOT touched here.
const _usageCacheCleanupTimer = setInterval(() => {
  const now = Date.now();
  for (const [key, entry] of _geminiCliSubCache) {
    if (now - entry.fetchedAt > GEMINI_CLI_CACHE_TTL_MS) _geminiCliSubCache.delete(key);
  }
  for (const [key, entry] of _antigravitySubCache) {
    if (now - entry.fetchedAt > ANTIGRAVITY_CACHE_TTL_MS) _antigravitySubCache.delete(key);
  }
  for (const [key, entry] of _antigravityAvailableModelsCache) {
    if (now - entry.fetchedAt > ANTIGRAVITY_MODELS_CACHE_TTL_MS) _antigravityAvailableModelsCache.delete(key);
  }
  for (const [key, entry] of _antigravityCreditProbeCache) {
    if (now - entry.fetchedAt > ANTIGRAVITY_CREDIT_PROBE_TTL_MS) _antigravityCreditProbeCache.delete(key);
  }
}, 5 * 60 * 1000); // every 5 minutes
_usageCacheCleanupTimer.unref?.(); // Don't prevent process exit

interface AntigravityUsageOptions {
  forceRefresh?: boolean;
}

function buildAntigravityUsageCacheKey(accessToken: string, projectId?: string | null): string {
  return `${accessToken.substring(0, 16)}:${projectId || "default"}`;
}

async function fetchAntigravityAvailableModelsCached(
  accessToken: string,
  projectId?: string | null,
  options: AntigravityUsageOptions = {}
): Promise<unknown> {
  if (!accessToken) throw new Error("Access token is required");

  const cacheKey = buildAntigravityUsageCacheKey(accessToken, projectId);
  const cached = _antigravityAvailableModelsCache.get(cacheKey);
  if (
    !options.forceRefresh &&
    cached &&
    Date.now() - cached.fetchedAt < ANTIGRAVITY_MODELS_CACHE_TTL_MS
  ) {
    return cached.data;
  }

  const inflight = _antigravityAvailableModelsInflight.get(cacheKey);
  if (inflight) return inflight;

  const promise = (async () => {
    let response: Response | null = null;
    let lastError: Error | null = null;

    for (const quotaApiUrl of ANTIGRAVITY_CONFIG.quotaApiUrls) {
      try {
        response = await fetch(quotaApiUrl, {
          method: "POST",
          headers: getAntigravityHeaders("fetchAvailableModels", accessToken),
          body: JSON.stringify(projectId ? { project: projectId } : {}),
          signal: AbortSignal.timeout(10000),
        });

        if (response.ok || response.status === 401 || response.status === 403) {
          break;
        }
      } catch (error) {
        lastError = error as Error;
      }
    }

    if (!response) {
      throw lastError || new Error("Antigravity API unavailable");
    }

    if (response.status === 403) {
      return { __antigravityForbidden: true };
    }

    if (!response.ok) {
      throw new Error(`Antigravity API error: ${response.status}`);
    }

    const data = await response.json();
    _antigravityAvailableModelsCache.set(cacheKey, { data, fetchedAt: Date.now() });
    return data;
  })().finally(() => {
    _antigravityAvailableModelsInflight.delete(cacheKey);
  });

  _antigravityAvailableModelsInflight.set(cacheKey, promise);
  return promise;
}

function extractCodeAssistTierId(subscription: JsonRecord): string {
  const tierId = extractCodeAssistOnboardTierId(subscription);
  if (tierId === "legacy-tier") return "";
  const upper = tierId.toUpperCase();
  return mapCodeAssistTierIdToLabel(upper) ? upper : "";
}

function mapCodeAssistTierIdToLabel(tierId: string): string | null {
  const upper = tierId.toUpperCase();
  if (upper.includes("ULTRA")) return "Ultra";
  if (
    upper.includes("PRO") ||
    upper.includes("PREMIUM") ||
    upper.includes("GOOGLE_ONE") ||
    upper.includes("ONE_AI")
  )
    return "Pro";
  if (upper.includes("ENTERPRISE")) return "Enterprise";
  if (upper.includes("BUSINESS") || upper.includes("STANDARD")) return "Business";
  if (upper.includes("PLUS")) return "Plus";
  if (upper.includes("LITE") || upper.includes("LIGHT")) return "Lite";
  if (upper.includes("FREE") || upper.includes("INDIVIDUAL") || upper.includes("LEGACY"))
    return "Free";
  return null;
}

function mapSubscriptionTierStringToPlanLabel(tierText: string): string | null {
  const upper = tierText.toUpperCase();
  if (upper.includes("ULTRA")) return "Ultra";
  if (upper.includes("PRO") || upper.includes("PREMIUM") || upper.includes("GOOGLE ONE"))
    return "Pro";
  if (upper.includes("ENTERPRISE")) return "Enterprise";
  if (upper.includes("STANDARD") || upper.includes("BUSINESS")) return "Business";
  if (upper.includes("PLUS")) return "Plus";
  if (upper.includes("LITE")) return "Lite";
  if (upper.includes("INDIVIDUAL") || upper.includes("FREE")) return "Free";
  // Strip a trailing "(RESTRICTED)" marker. Match the fixed literal anywhere then
  // trim, instead of /\s*\(RESTRICTED\)\s*$/ whose overlapping \s* runs backtrack
  // polynomially on whitespace-heavy upstream input (js/polynomial-redos).
  const normalizedId = upper.replace(/\(RESTRICTED\)/i, "").trim();
  if (normalizedId) {
    const mapped = mapCodeAssistTierIdToLabel(normalizedId);
    if (mapped) return mapped;
  }
  return null;
}

function mapCodeAssistSubscriptionToPlanLabel(subscriptionInfo: unknown): string {
  const subscription = toRecord(subscriptionInfo);
  if (Object.keys(subscription).length === 0) return "Free";

  const subscriptionTier = extractCodeAssistSubscriptionTier(subscriptionInfo);
  if (subscriptionTier) {
    const mapped = mapSubscriptionTierStringToPlanLabel(subscriptionTier);
    if (mapped) return mapped;
    if (subscriptionTier.toLowerCase() !== "free") {
      return subscriptionTier.charAt(0).toUpperCase() + subscriptionTier.slice(1).toLowerCase();
    }
  }

  const currentTier = toRecord(subscription.currentTier);
  const tierName = String(
    getFieldValue(currentTier, "name", "displayName") ||
      subscription.subscriptionType ||
      subscription.tier ||
      ""
  );
  const mappedName = tierName ? mapSubscriptionTierStringToPlanLabel(tierName) : null;
  if (mappedName) return mappedName;

  const tierId = extractCodeAssistTierId(subscription);
  if (tierId) {
    const mapped = mapCodeAssistTierIdToLabel(tierId);
    if (mapped) return mapped;
  }
  if (currentTier.upgradeSubscriptionType) return "Free";
  if (tierName) return tierName.charAt(0).toUpperCase() + tierName.slice(1).toLowerCase();
  return "Free";
}

const KNOWN_ANTIGRAVITY_PLAN_LABELS = new Set([
  "Ultra",
  "Pro",
  "Enterprise",
  "Business",
  "Plus",
  "Lite",
]);

/**
 * Map raw loadCodeAssist tier data to short display labels (Antigravity Manager parity).
 */
function getAntigravityPlanLabel(subscriptionInfo: unknown, fallbackInfo?: unknown): string {
  const livePlan = mapCodeAssistSubscriptionToPlanLabel(subscriptionInfo);
  const fallbackPlan = mapCodeAssistSubscriptionToPlanLabel(fallbackInfo);

  if (KNOWN_ANTIGRAVITY_PLAN_LABELS.has(livePlan)) return livePlan;
  if (KNOWN_ANTIGRAVITY_PLAN_LABELS.has(fallbackPlan)) return fallbackPlan;
  if (livePlan !== "Free") return livePlan;
  return fallbackPlan !== "Free" ? fallbackPlan : livePlan;
}

/**
 * Proactive credit balance probe for Antigravity.
 *
 * Fires a minimal streamGenerateContent request with GOOGLE_ONE_AI credits enabled
 * and maxOutputTokens=1 to extract the `remainingCredits` field from the SSE stream.
 * This uses ~1 credit but lets us show the balance on the dashboard without waiting
 * for a real user request.
 *
 * Returns the credit balance, or null if the probe failed.
 */
async function probeAntigravityCreditBalance(
  accessToken: string,
  accountId: string,
  projectId?: string | null,
  options: AntigravityUsageOptions = {},
  providerSpecificData: JsonRecord = {}
): Promise<number | null> {
  if (!accessToken) return null;

  const cacheKey = buildAntigravityUsageCacheKey(accessToken, projectId || accountId);
  const cached = _antigravityCreditProbeCache.get(cacheKey);
  if (
    !options.forceRefresh &&
    cached &&
    Date.now() - cached.fetchedAt < ANTIGRAVITY_CREDIT_PROBE_TTL_MS
  ) {
    return cached.data;
  }

  const inflight = _antigravityCreditProbeInflight.get(cacheKey);
  if (inflight) return inflight;

  const promise = probeAntigravityCreditBalanceUncached(
    accessToken,
    accountId,
    projectId,
    providerSpecificData
  )
    .then(
      (data) => {
        _antigravityCreditProbeCache.set(cacheKey, { data, fetchedAt: Date.now() });
        return data;
      },
      (error) => {
        _antigravityCreditProbeCache.set(cacheKey, { data: null, fetchedAt: Date.now() });
        throw error;
      }
    )
    .finally(() => {
      _antigravityCreditProbeInflight.delete(cacheKey);
    });

  _antigravityCreditProbeInflight.set(cacheKey, promise);
  return promise;
}

async function probeAntigravityCreditBalanceUncached(
  accessToken: string,
  accountId: string,
  projectId?: string | null,
  providerSpecificData: JsonRecord = {}
): Promise<number | null> {
  try {
    if (!projectId) return null;

    // Try all base URLs (some accounts only work with specific endpoints)
    for (const baseUrl of ANTIGRAVITY_BASE_URLS) {
      const url = `${baseUrl}/v1internal:streamGenerateContent?alt=sse`;

      const sessionId = getAntigravitySessionId({ connectionId: accountId, projectId });
      const body = {
        project: projectId,
        model: "gemini-2-flash",
        userAgent: "antigravity",
        requestType: "agent",
        requestId: generateAntigravityRequestId(),
        enabledCreditTypes: ["GOOGLE_ONE_AI"],
        request: {
          model: "gemini-2-flash",
          contents: [{ role: "user", parts: [{ text: "hi" }] }],
          generationConfig: { maxOutputTokens: 1 },
          sessionId,
        },
      };

      const headers: Record<string, string> = {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
        Accept: "text/event-stream",
      };
      applyAntigravityClientProfileHeaders(
        headers,
        { connectionId: accountId, projectId, providerSpecificData },
        body
      );

      try {
        const res = await fetch(url, {
          method: "POST",
          headers,
          body: JSON.stringify(body),
          signal: AbortSignal.timeout(10_000),
        });

        if (!res.ok) continue;

        // Read the full SSE response and scan for remainingCredits
        const rawSSE = await res.text();
        const lines = rawSSE.split("\n");

        for (const line of lines) {
          const trimmed = line.trim();
          if (!trimmed.startsWith("data:")) continue;
          const payload = trimmed.slice(5).trim();
          if (payload === "[DONE]") break;
          try {
            const parsed = JSON.parse(payload);
            if (Array.isArray(parsed?.remainingCredits)) {
              const googleCredit = parsed.remainingCredits.find(
                (c: { creditType?: string }) => c?.creditType === "GOOGLE_ONE_AI"
              );
              if (googleCredit) {
                const balance = parseInt(googleCredit.creditAmount, 10);
                if (!isNaN(balance)) {
                  updateAntigravityRemainingCredits(accountId, balance);
                  return balance;
                }
              }
            }
          } catch {
            // Skip malformed SSE lines
          }
        }
      } catch {
        // Individual endpoint failure; try next
      }
    }

    return null;
  } catch {
    // Probe is best-effort — don't let it break the usage fetch
    return null;
  }
}

/**
 * Antigravity Usage - Fetch quota from Google Cloud Code API
 * Uses fetchAvailableModels API which returns ALL models (including Claude)
 * with per-model quotaInfo (remainingFraction, resetTime).
 * retrieveUserQuota only returns Gemini models — not suitable for Antigravity.
 */
async function getAntigravityUsage(
  accessToken?: string,
  providerSpecificData?: JsonRecord,
  connectionProjectId?: string,
  connectionId?: string,
  options: AntigravityUsageOptions = {}
) {
  if (!accessToken) {
    return { plan: "Free", message: "Antigravity access token not available." };
  }

  let subscriptionInfo: unknown = null;
  try {
    subscriptionInfo = await getAntigravitySubscriptionInfoCached(
      accessToken,
      providerSpecificData,
      options
    );
    const savedProjectId =
      typeof providerSpecificData?.projectId === "string" && providerSpecificData.projectId.trim()
        ? providerSpecificData.projectId.trim()
        : null;
    const subscriptionProject = toRecord(subscriptionInfo).cloudaicompanionProject;
    const projectId =
      savedProjectId ||
      connectionProjectId ||
      (typeof subscriptionProject === "string"
        ? subscriptionProject
        : typeof toRecord(subscriptionProject).id === "string"
          ? (toRecord(subscriptionProject).id as string)
          : null);

    // Derive accountId for credit balance cache.
    // Must match executor key: credentials.connectionId
    const accountId: string = connectionId || "unknown";

    // Read cached credit balance (hydrated from DB on first access)
    let creditBalance = getAntigravityRemainingCredits(accountId);

    // If no cached balance and credits mode is enabled, fire a minimal probe
    const creditsMode = getCreditsMode();
    if ((options.forceRefresh || creditBalance === null) && creditsMode !== "off") {
      creditBalance = await probeAntigravityCreditBalance(
        accessToken,
        accountId,
        projectId,
        options,
        providerSpecificData || {}
      );
    }

    const data = await fetchAntigravityAvailableModelsCached(accessToken, projectId, options);
    const dataObj = toRecord(data);
    if (dataObj.__antigravityForbidden === true) {
      return { message: "Antigravity access forbidden. Check subscription." };
    }
    const modelEntries = toRecord(dataObj.models);
    const quotas: Record<string, UsageQuota> = {};

    // Parse per-model quota info from fetchAvailableModels response.
    for (const [modelKey, infoValue] of Object.entries(modelEntries)) {
      const info = toRecord(infoValue);
      const quotaInfo = toRecord(info.quotaInfo);

      // Skip internal, excluded, and models without quota info
      if (
        info.isInternal === true ||
        !isUserCallableAntigravityModelId(modelKey) ||
        Object.keys(quotaInfo).length === 0
      ) {
        continue;
      }

      const rawFraction = toNumber(quotaInfo.remainingFraction, -1);
      const resetAt = parseResetTime(quotaInfo.resetTime);
      // Distinguish "upstream did not report remainingFraction" from "remaining is 0%".
      // A schema drift in Antigravity's quota API (very plausible — internal Google product)
      // would otherwise silently mark every model as exhausted across the dashboard.
      const fractionReported = rawFraction >= 0;
      if (!fractionReported) {
        console.warn(
          `[Antigravity] model ${modelKey} returned no remainingFraction — quota unknown`
        );
      }
      const remainingFraction = fractionReported ? Math.max(0, Math.min(1, rawFraction)) : 0;
      // Models with no resetTime AND a reported full fraction are unlimited
      // (e.g. tab-completion models). Unreported fraction is NEVER unlimited.
      const isUnlimited = fractionReported && !resetAt && remainingFraction >= 1;
      const remainingPercentage = remainingFraction * 100;
      const QUOTA_NORMALIZED_BASE = 1000;
      const total = QUOTA_NORMALIZED_BASE;
      const remaining = Math.round(total * remainingFraction);
      const used = isUnlimited ? 0 : Math.max(0, total - remaining);

      quotas[modelKey] = {
        used,
        total: isUnlimited ? 0 : total,
        resetAt,
        remainingPercentage: isUnlimited ? 100 : remainingPercentage,
        unlimited: isUnlimited,
        fractionReported,
      };
    }

    return {
      plan: getAntigravityPlanLabel(subscriptionInfo, providerSpecificData),
      quotas: {
        ...quotas,
        ...(creditBalance !== null && {
          credits: {
            used: 0,
            total: 0,
            remaining: creditBalance,
            unlimited: false,
            resetAt: null,
          },
        }),
      },
      subscriptionInfo,
    };
  } catch (error) {
    return {
      plan: getAntigravityPlanLabel(subscriptionInfo, providerSpecificData),
      subscriptionInfo,
      message: `Antigravity error: ${(error as Error).message}`,
    };
  }
}

/**
 * Get Antigravity subscription info (cached, 5 min TTL)
 * Prevents duplicate loadCodeAssist calls within the same quota cycle.
 */
async function getAntigravitySubscriptionInfoCached(
  accessToken: string,
  providerSpecificData?: JsonRecord,
  options: AntigravityUsageOptions = {}
): Promise<unknown> {
  const profile = getAntigravityClientProfile({ providerSpecificData });
  const cacheKey = `${accessToken.substring(0, 16)}:${profile}`;

  if (options.forceRefresh) {
    _antigravitySubCache.delete(cacheKey);
  } else {
    const cached = _antigravitySubCache.get(cacheKey);
    if (cached && Date.now() - cached.fetchedAt < ANTIGRAVITY_CACHE_TTL_MS) {
      return cached.data;
    }
  }

  const data = await getAntigravitySubscriptionInfo(accessToken, providerSpecificData);
  if (data != null) {
    _antigravitySubCache.set(cacheKey, { data, fetchedAt: Date.now() });
  }
  return data;
}

/**
 * Get Antigravity subscription info using correct Antigravity headers.
 * Must match the headers used in providers.js postExchange (not CLI headers).
 */
async function getAntigravitySubscriptionInfo(
  accessToken: string,
  providerSpecificData?: JsonRecord
): Promise<unknown | null> {
  try {
    const profile = getAntigravityClientProfile({ providerSpecificData });
    const response = await fetch(ANTIGRAVITY_CONFIG.loadProjectApiUrl, {
      method: "POST",
      headers:
        profile === "harness"
          ? getAntigravityBootstrapHeaders(profile, accessToken)
          : getAntigravityHeaders("loadCodeAssist", accessToken),
      body: JSON.stringify({ metadata: getAntigravityLoadCodeAssistMetadata() }),
    });

    if (!response.ok) return null;

    return await response.json();
  } catch {
    return null;
  }
}

/**
 * Claude Usage - Try to fetch from Anthropic API
 */
async function getClaudeUsage(accessToken?: string) {
  if (!accessToken) {
    return { message: "Claude connected. Access token not available.", bootstrap: null };
  }

  // Refresh bootstrap in parallel; best-effort, failure non-fatal.
  const bootstrapPromise = fetchClaudeBootstrap(accessToken).catch(() => null);
  try {
    // Real CLI uses axios here, not Stainless — UA is `claude-code/<version>`
    // (not `claude-cli/...`) and the shape is simpler than /v1/messages.
    const ctrl = new AbortController();
    const timer = setTimeout(() => ctrl.abort(), 10_000);
    let oauthResponse;
    try {
      oauthResponse = await fetch(CLAUDE_CONFIG.oauthUsageUrl, {
        method: "GET",
        headers: {
          Accept: "application/json, text/plain, */*",
          "Accept-Encoding": "gzip, compress, deflate, br",
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json",
          "User-Agent": `claude-code/${CLAUDE_CODE_VERSION}`,
          "anthropic-beta": "oauth-2025-04-20",
        },
        signal: ctrl.signal,
      });
    } finally {
      clearTimeout(timer);
    }

    if (oauthResponse.ok) {
      const data = toRecord(await oauthResponse.json());
      const quotas: Record<string, UsageQuota> = {};

      // utilization = percentage USED (e.g., 90 means 90% used, 10% remaining)
      // Confirmed via user report #299: Claude.ai shows 87% used = OmniRoute must show 13% remaining.
      const hasUtilization = (window: JsonRecord) =>
        window && typeof window === "object" && safePercentage(window.utilization) !== undefined;

      const createQuotaObject = (window: JsonRecord) => {
        const used = safePercentage(window.utilization) as number; // utilization = % used
        const remaining = Math.max(0, 100 - used);
        return {
          used,
          total: 100,
          remaining,
          resetAt: parseResetTime(window.resets_at),
          remainingPercentage: remaining,
          unlimited: false,
        };
      };

      const fiveHour = toRecord(data.five_hour);
      if (hasUtilization(fiveHour)) {
        quotas["session (5h)"] = createQuotaObject(fiveHour);
      }

      const sevenDay = toRecord(data.seven_day);
      if (hasUtilization(sevenDay)) {
        quotas["weekly (7d)"] = createQuotaObject(sevenDay);
      }

      // Map Anthropic's internal codenames (e.g., omelette → Designer) for display.
      const MODEL_DISPLAY_NAMES: Record<string, string> = {
        omelette: "designer",
      };
      for (const [key, value] of Object.entries(data)) {
        const valueRecord = toRecord(value);
        if (key.startsWith("seven_day_") && key !== "seven_day" && hasUtilization(valueRecord)) {
          const codename = key.replace("seven_day_", "");
          const modelName = MODEL_DISPLAY_NAMES[codename] || codename;
          quotas[`weekly ${modelName} (7d)`] = createQuotaObject(valueRecord);
        }
      }

      const bootstrap = await bootstrapPromise;
      const plan =
        getClaudePlanLabel(
          typeof data.tier === "string" ? data.tier : null,
          typeof data.plan === "string" ? data.plan : null,
          typeof data.subscription_type === "string" ? data.subscription_type : null,
          bootstrap?.organization_rate_limit_tier
        ) ?? undefined;

      return {
        ...(plan ? { plan } : {}),
        quotas,
        extraUsage: data.extra_usage ?? null,
        bootstrap,
      };
    }

    // Fallback: OAuth endpoint returned non-OK, try legacy settings/org endpoint
    console.warn(
      `[Claude Usage] OAuth endpoint returned ${oauthResponse.status}, falling back to legacy`
    );
    const legacy = await getClaudeUsageLegacy(accessToken);
    return { ...legacy, bootstrap: await bootstrapPromise };
  } catch (error) {
    return {
      message: `Claude connected. Unable to fetch usage: ${(error as Error).message}`,
      bootstrap: await bootstrapPromise,
    };
  }
}

/**
 * Legacy Claude usage fetcher for API key / org admin users.
 * Uses /v1/settings + /v1/organizations/{org_id}/usage endpoints.
 */
async function getClaudeUsageLegacy(accessToken?: string) {
  try {
    const settingsResponse = await fetch(CLAUDE_CONFIG.settingsUrl, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "anthropic-version": CLAUDE_CONFIG.apiVersion,
      },
    });

    if (settingsResponse.ok) {
      const settings = toRecord(await settingsResponse.json());

      const organizationId =
        typeof settings.organization_id === "string" ? settings.organization_id : "";
      if (organizationId) {
        const usageResponse = await fetch(
          CLAUDE_CONFIG.usageUrl.replace("{org_id}", organizationId),
          {
            method: "GET",
            headers: {
              Authorization: `Bearer ${accessToken}`,
              "anthropic-version": CLAUDE_CONFIG.apiVersion,
            },
          }
        );

        if (usageResponse.ok) {
          const usage = await usageResponse.json();
          return {
            plan: settings.plan || "Unknown",
            organization: settings.organization_name,
            quotas: usage,
          };
        }
      }

      return {
        plan: settings.plan || "Unknown",
        organization: settings.organization_name,
        message: "Claude connected. Usage details require admin access.",
      };
    }

    return { message: "Claude connected. Usage API requires admin permissions." };
  } catch (error) {
    return { message: `Claude connected. Unable to fetch usage: ${(error as Error).message}` };
  }
}

/**
 * Codex (OpenAI) Usage - Fetch from ChatGPT backend API
 * IMPORTANT: Uses persisted workspaceId from OAuth to ensure correct workspace binding.
 * No fallback to other workspaces - strict binding to user's selected workspace.
 */
async function getCodexUsage(
  accessToken?: string,
  providerSpecificData: Record<string, unknown> = {}
) {
  try {
    // Use persisted workspace ID from OAuth - NO FALLBACK
    const accountId =
      typeof providerSpecificData.workspaceId === "string"
        ? providerSpecificData.workspaceId
        : null;

    const headers: Record<string, string> = {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
      Accept: "application/json",
    };
    if (accountId) {
      headers["chatgpt-account-id"] = accountId;
    }

    const response = await fetch(CODEX_CONFIG.usageUrl, {
      method: "GET",
      headers,
    });

    if (!response.ok) {
      if (response.status === 401 || response.status === 403) {
        return {
          message: `Codex token expired or access denied. Please re-authenticate the connection.`,
        };
      }
      throw new Error(`Codex API error: ${response.status}`);
    }

    const data = await response.json();

    // Parse rate limit info (supports both snake_case and camelCase)
    const rateLimit = toRecord(getFieldValue(data, "rate_limit", "rateLimit"));
    const primaryWindow = toRecord(getFieldValue(rateLimit, "primary_window", "primaryWindow"));
    const secondaryWindow = toRecord(
      getFieldValue(rateLimit, "secondary_window", "secondaryWindow")
    );

    // Parse reset times (reset_at is Unix timestamp in seconds)
    const parseWindowReset = (window: unknown) => {
      const resetAt = toNumber(getFieldValue(window, "reset_at", "resetAt"), 0);
      const resetAfterSeconds = toNumber(
        getFieldValue(window, "reset_after_seconds", "resetAfterSeconds"),
        0
      );
      if (resetAt > 0) return parseResetTime(resetAt * 1000);
      if (resetAfterSeconds > 0) return parseResetTime(Date.now() + resetAfterSeconds * 1000);
      return null;
    };

    // Build quota windows
    const quotas: Record<string, UsageQuota> = {};

    // Primary window (5-hour)
    if (Object.keys(primaryWindow).length > 0) {
      const usedPercent = toNumber(getFieldValue(primaryWindow, "used_percent", "usedPercent"), 0);
      quotas.session = {
        used: usedPercent,
        total: 100,
        remaining: 100 - usedPercent,
        resetAt: parseWindowReset(primaryWindow),
        unlimited: false,
      };
    }

    // Secondary window (weekly)
    if (Object.keys(secondaryWindow).length > 0) {
      const usedPercent = toNumber(
        getFieldValue(secondaryWindow, "used_percent", "usedPercent"),
        0
      );
      quotas.weekly = {
        used: usedPercent,
        total: 100,
        remaining: 100 - usedPercent,
        resetAt: parseWindowReset(secondaryWindow),
        unlimited: false,
      };
    }

    // Code review rate limit (3rd window — differs per plan: Plus/Pro/Team)
    const codeReviewRateLimit = toRecord(
      getFieldValue(data, "code_review_rate_limit", "codeReviewRateLimit")
    );
    const codeReviewWindow = toRecord(
      getFieldValue(codeReviewRateLimit, "primary_window", "primaryWindow")
    );

    // Only include code review quota if the API returned data for it
    const codeReviewUsedRaw = getFieldValue(codeReviewWindow, "used_percent", "usedPercent");
    const codeReviewRemainingRaw = getFieldValue(
      codeReviewWindow,
      "remaining_count",
      "remainingCount"
    );
    if (codeReviewUsedRaw !== null || codeReviewRemainingRaw !== null) {
      const codeReviewUsedPercent = toNumber(codeReviewUsedRaw, 0);
      quotas.code_review = {
        used: codeReviewUsedPercent,
        total: 100,
        remaining: 100 - codeReviewUsedPercent,
        resetAt: parseWindowReset(codeReviewWindow),
        unlimited: false,
      };
    }

    return {
      plan: String(getFieldValue(data, "plan_type", "planType") || "unknown"),
      limitReached: Boolean(getFieldValue(rateLimit, "limit_reached", "limitReached")),
      quotas,
    };
  } catch (error) {
    return { message: `Failed to fetch Codex usage: ${(error as Error).message}` };
  }
}

/**
 * Kiro (AWS CodeWhisperer) Usage
 */
async function getKiroUsage(accessToken?: string, providerSpecificData?: JsonRecord) {
  try {
    const profileArn = providerSpecificData?.profileArn;
    if (!profileArn) {
      return { message: "Kiro connected. Profile ARN not available for quota tracking." };
    }

    // Kiro uses AWS CodeWhisperer GetUsageLimits API
    const payload = {
      origin: "AI_EDITOR",
      profileArn: profileArn,
      resourceType: "AGENTIC_REQUEST",
    };

    const response = await fetch(CODEWHISPERER_BASE_URL, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/x-amz-json-1.0",
        "x-amz-target": "AmazonCodeWhispererService.GetUsageLimits",
        Accept: "application/json",
      },
      body: JSON.stringify(payload),
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Kiro API error (${response.status}): ${errorText}`);
    }

    const data = toRecord(await response.json());

    // Parse usage data from usageBreakdownList
    const usageList = Array.isArray(data.usageBreakdownList) ? data.usageBreakdownList : [];
    const quotaInfo: Record<string, UsageQuota> = {};

    // Parse reset time - supports multiple formats (nextDateReset, resetDate, etc.)
    const resetAt = parseResetTime(data.nextDateReset || data.resetDate);

    usageList.forEach((breakdownValue: unknown) => {
      const breakdown = toRecord(breakdownValue);
      const resourceType =
        typeof breakdown.resourceType === "string"
          ? breakdown.resourceType.toLowerCase()
          : "unknown";
      const used = toNumber(breakdown.currentUsageWithPrecision, 0);
      const total = toNumber(breakdown.usageLimitWithPrecision, 0);

      quotaInfo[resourceType] = {
        used,
        total,
        remaining: total - used,
        resetAt,
        unlimited: false,
      };

      // Add free trial if available
      const freeTrialInfo = toRecord(breakdown.freeTrialInfo);
      if (Object.keys(freeTrialInfo).length > 0) {
        const freeUsed = toNumber(freeTrialInfo.currentUsageWithPrecision, 0);
        const freeTotal = toNumber(freeTrialInfo.usageLimitWithPrecision, 0);

        quotaInfo[`${resourceType}_freetrial`] = {
          used: freeUsed,
          total: freeTotal,
          remaining: freeTotal - freeUsed,
          resetAt,
          unlimited: false,
        };
      }
    });

    return {
      plan: String(toRecord(data.subscriptionInfo).subscriptionTitle || "").trim() || "Kiro",
      quotas: quotaInfo,
    };
  } catch (error) {
    throw new Error(`Failed to fetch Kiro usage: ${error.message}`);
  }
}

/**
 * Map Kimi membership level to display name
 * LEVEL_BASIC = Moderato, LEVEL_INTERMEDIATE = Allegretto,
 * LEVEL_ADVANCED = Allegro, LEVEL_STANDARD = Vivace
 */
function getKimiPlanName(level: unknown): string {
  if (!level) return "";
  const normalizedLevel = String(level);

  const levelMap = {
    LEVEL_BASIC: "Moderato",
    LEVEL_INTERMEDIATE: "Allegretto",
    LEVEL_ADVANCED: "Allegro",
    LEVEL_STANDARD: "Vivace",
  };

  return (
    levelMap[normalizedLevel as keyof typeof levelMap] ||
    normalizedLevel.replace("LEVEL_", "").toLowerCase()
  );
}

/**
 * Kimi Coding Usage - Fetch quota from Kimi API
 * Uses the official /v1/usages endpoint with custom X-Msh-* headers
 */
async function getKimiUsage(accessToken?: string) {
  // Generate device info for headers (same as OAuth flow)
  const deviceId = "kimi-usage-" + Date.now();
  const platform = "omniroute";
  const version = "2.1.2";
  const deviceModel =
    typeof process !== "undefined" ? `${process.platform} ${process.arch}` : "unknown";

  try {
    const response = await fetch(KIMI_CONFIG.usageUrl, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
        "X-Msh-Platform": platform,
        "X-Msh-Version": version,
        "X-Msh-Device-Model": deviceModel,
        "X-Msh-Device-Id": deviceId,
      },
    });

    const responseText = await response.text();

    if (!response.ok) {
      return {
        plan: "Kimi Coding",
        message: `Kimi Coding connected. API Error ${response.status}: ${responseText.slice(0, 100)}`,
      };
    }

    let data;
    try {
      data = JSON.parse(responseText);
    } catch {
      return {
        plan: "Kimi Coding",
        message: "Kimi Coding connected. Invalid JSON response from API.",
      };
    }

    const quotas: Record<string, UsageQuota> = {};
    const dataObj = toRecord(data);

    // Parse Kimi usage response format
    // Format: { user: {...}, usage: { limit: "100", used: "92", remaining: "8", resetTime: "..." }, limits: [...] }
    const usageObj = toRecord(dataObj.usage);

    // Check for Kimi's actual usage fields (strings, not numbers)
    const usageLimit = toNumber(usageObj.limit || usageObj.Limit, 0);
    const usageUsed = toNumber(usageObj.used || usageObj.Used, 0);
    const usageRemaining = toNumber(usageObj.remaining || usageObj.Remaining, 0);
    const usageResetTime =
      usageObj.resetTime || usageObj.ResetTime || usageObj.reset_at || usageObj.resetAt;

    if (usageLimit > 0) {
      const percentRemaining = usageLimit > 0 ? (usageRemaining / usageLimit) * 100 : 0;

      quotas["Weekly"] = {
        used: usageUsed,
        total: usageLimit,
        remaining: usageRemaining,
        remainingPercentage: percentRemaining,
        resetAt: parseResetTime(usageResetTime),
        unlimited: false,
      };
    }

    // Also parse limits array for rate limits
    const limitsArray = Array.isArray(dataObj.limits) ? dataObj.limits : [];
    for (let i = 0; i < limitsArray.length; i++) {
      const limitItem = toRecord(limitsArray[i]);
      const window = toRecord(limitItem.window);
      const detail = toRecord(limitItem.detail);

      const limit = toNumber(detail.limit || detail.Limit, 0);
      const remaining = toNumber(detail.remaining || detail.Remaining, 0);
      const resetTime = detail.resetTime || detail.reset_at || detail.resetAt;

      if (limit > 0) {
        quotas["Ratelimit"] = {
          used: limit - remaining,
          total: limit,
          remaining,
          remainingPercentage: limit > 0 ? (remaining / limit) * 100 : 0,
          resetAt: parseResetTime(resetTime),
          unlimited: false,
        };
      }
    }

    // Check for quota windows (Claude-like format with utilization) as fallback
    const hasUtilization = (window: JsonRecord) =>
      window && typeof window === "object" && safePercentage(window.utilization) !== undefined;

    const createQuotaObject = (window: JsonRecord) => {
      const remaining = safePercentage(window.utilization) as number;
      const used = 100 - remaining;
      return {
        used,
        total: 100,
        remaining,
        resetAt: parseResetTime(window.resets_at),
        remainingPercentage: remaining,
        unlimited: false,
      };
    };

    if (hasUtilization(toRecord(dataObj.five_hour))) {
      quotas["session (5h)"] = createQuotaObject(toRecord(dataObj.five_hour));
    }

    if (hasUtilization(toRecord(dataObj.seven_day))) {
      quotas["weekly (7d)"] = createQuotaObject(toRecord(dataObj.seven_day));
    }

    // Check for model-specific quotas
    for (const [key, value] of Object.entries(dataObj)) {
      const valueRecord = toRecord(value);
      if (key.startsWith("seven_day_") && key !== "seven_day" && hasUtilization(valueRecord)) {
        const modelName = key.replace("seven_day_", "");
        quotas[`weekly ${modelName} (7d)`] = createQuotaObject(valueRecord);
      }
    }

    if (Object.keys(quotas).length > 0) {
      const userRecord = toRecord(dataObj.user);
      const membershipLevel = toRecord(userRecord.membership).level;
      const planName = getKimiPlanName(membershipLevel);
      return {
        plan: planName || "Kimi Coding",
        quotas,
      };
    }

    // No quota data in response
    const userRecord = toRecord(dataObj.user);
    const membershipLevel = toRecord(userRecord.membership).level;
    const planName = getKimiPlanName(membershipLevel);
    return {
      plan: planName || "Kimi Coding",
      message: "Kimi Coding connected. Usage tracked per request.",
    };
  } catch (error) {
    return {
      message: `Kimi Coding connected. Unable to fetch usage: ${(error as Error).message}`,
    };
  }
}

/**
 * Qwen Usage
 */
async function getQwenUsage(accessToken?: string, providerSpecificData?: JsonRecord) {
  void accessToken;
  try {
    const resourceUrl = providerSpecificData?.resourceUrl;
    if (!resourceUrl) {
      return { message: "Qwen connected. No resource URL available." };
    }

    // Qwen may have usage endpoint at resource URL
    return { message: "Qwen connected. Usage tracked per request." };
  } catch (error) {
    return { message: "Unable to fetch Qwen usage." };
  }
}

/**
 * Qoder Usage
 */
async function getQoderUsage(accessToken?: string) {
  void accessToken;
  try {
    // Qoder may have usage endpoint
    return { message: "Qoder connected. Usage tracked per request." };
  } catch (error) {
    return { message: "Unable to fetch Qoder usage." };
  }
}

export const __testing = {
  parseResetTime,
  formatGitHubQuotaSnapshot,
  inferGitHubPlanName,
  getGeminiCliPlanLabel,
  getAntigravityPlanLabel,
  extractCodeAssistSubscriptionTier,
  extractCodeAssistOnboardTierId,
  getMiniMaxPlanLabel,
  inferMiniMaxPlanLabelFromTotals,
  getOpencodeUsage,
  getClaudePlanLabel,
  createQuotaFromUsage,
  getMiniMaxQuotaResetAt,
  isMiniMaxTextQuotaModel,
  getMiniMaxSessionTotal,
  getMiniMaxWeeklyTotal,
  createMiniMaxQuotaFromCount,
  createMiniMaxQuotaFromPercent,
  getMiniMaxRemainingPercent,
  getMiniMaxUsage,
  getXiaomiMimoUsage,
  getMiniMaxAuthErrorMessage,
  getMiniMaxErrorSummary,
  mapCodeAssistSubscriptionToPlanLabel,
  mapCodeAssistTierIdToLabel,
  mapSubscriptionTierStringToPlanLabel,
  toDisplayLabel,
};
