import {
  resolveAgentDir,
  resolveDefaultAgentId,
  resolveSessionAgentId,
} from "../../agents/agent-scope.js";
import {
  ensureAuthProfileStore,
  resolveAuthProfileDisplayLabel,
  resolveAuthProfileOrder,
} from "../../agents/auth-profiles.js";
import { buildAuthHealthSummary, formatRemainingShort } from "../../agents/auth-health.js";
import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-auth.js";
import { normalizeProviderId } from "../../agents/model-selection.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { SessionEntry, SessionScope } from "../../config/sessions.js";
import { logVerbose } from "../../globals.js";
import {
  formatUsageSummaryLine,
  formatUsageWindowSummary,
  loadProviderUsageSummary,
  resolveUsageProviderId,
  type UsageProviderId,
} from "../../infra/provider-usage.js";
import { normalizeGroupActivation } from "../group-activation.js";
import { buildStatusMessage } from "../status.js";
import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "../thinking.js";
import type { ReplyPayload } from "../types.js";
import type { CommandContext } from "./commands-types.js";
import { getFollowupQueueDepth, resolveQueueSettings } from "./queue.js";

function formatApiKeySnippet(apiKey: string): string {
  const compact = apiKey.replace(/\s+/g, "");
  if (!compact) return "unknown";
  const edge = compact.length >= 12 ? 6 : 4;
  const head = compact.slice(0, edge);
  const tail = compact.slice(-edge);
  return `${head}…${tail}`;
}

function resolveModelAuthLabel(
  provider?: string,
  cfg?: ClawdbotConfig,
  sessionEntry?: SessionEntry,
  agentDir?: string,
): string | undefined {
  const resolved = provider?.trim();
  if (!resolved) return undefined;

  const providerKey = normalizeProviderId(resolved);
  const store = ensureAuthProfileStore(agentDir, {
    allowKeychainPrompt: false,
  });
  const profileOverride = sessionEntry?.authProfileOverride?.trim();
  const order = resolveAuthProfileOrder({
    cfg,
    store,
    provider: providerKey,
    preferredProfile: profileOverride,
  });
  const candidates = [profileOverride, ...order].filter(Boolean) as string[];

  for (const profileId of candidates) {
    const profile = store.profiles[profileId];
    if (!profile || normalizeProviderId(profile.provider) !== providerKey) {
      continue;
    }
    const label = resolveAuthProfileDisplayLabel({ cfg, store, profileId });
    if (profile.type === "oauth") {
      return `oauth${label ? ` (${label})` : ""}`;
    }
    if (profile.type === "token") {
      const snippet = formatApiKeySnippet(profile.token);
      return `token ${snippet}${label ? ` (${label})` : ""}`;
    }
    const snippet = formatApiKeySnippet(profile.key);
    return `api-key ${snippet}${label ? ` (${label})` : ""}`;
  }

  const envKey = resolveEnvApiKey(providerKey);
  if (envKey?.apiKey) {
    if (envKey.source.includes("OAUTH_TOKEN")) {
      return `oauth (${envKey.source})`;
    }
    return `api-key ${formatApiKeySnippet(envKey.apiKey)} (${envKey.source})`;
  }

  const customKey = getCustomProviderApiKey(cfg, providerKey);
  if (customKey) {
    return `api-key ${formatApiKeySnippet(customKey)} (models.json)`;
  }

  return "unknown";
}

export async function buildStatusReply(params: {
  cfg: ClawdbotConfig;
  command: CommandContext;
  sessionEntry?: SessionEntry;
  sessionKey: string;
  sessionScope?: SessionScope;
  provider: string;
  model: string;
  contextTokens: number;
  resolvedThinkLevel?: ThinkLevel;
  resolvedVerboseLevel: VerboseLevel;
  resolvedReasoningLevel: ReasoningLevel;
  resolvedElevatedLevel?: ElevatedLevel;
  resolveDefaultThinkingLevel: () => Promise<ThinkLevel | undefined>;
  isGroup: boolean;
  defaultGroupActivation: () => "always" | "mention";
}): Promise<ReplyPayload | undefined> {
  const {
    cfg,
    command,
    sessionEntry,
    sessionKey,
    sessionScope,
    provider,
    model,
    contextTokens,
    resolvedThinkLevel,
    resolvedVerboseLevel,
    resolvedReasoningLevel,
    resolvedElevatedLevel,
    resolveDefaultThinkingLevel,
    isGroup,
    defaultGroupActivation,
  } = params;
  if (!command.isAuthorizedSender) {
    logVerbose(`Ignoring /status from unauthorized sender: ${command.senderId || "<unknown>"}`);
    return undefined;
  }
  const statusAgentId = sessionKey
    ? resolveSessionAgentId({ sessionKey, config: cfg })
    : resolveDefaultAgentId(cfg);
  const statusAgentDir = resolveAgentDir(cfg, statusAgentId);
  const authStore = ensureAuthProfileStore(statusAgentDir, { allowKeychainPrompt: false });
  const authHealth = buildAuthHealthSummary({ store: authStore, cfg });
  const oauthProfiles = authHealth.profiles.filter(
    (profile) => profile.type === "oauth" || profile.type === "token",
  );

  const usageProviders = new Set<UsageProviderId>();
  for (const profile of oauthProfiles) {
    const entry = resolveUsageProviderId(profile.provider);
    if (entry) usageProviders.add(entry);
  }
  const currentUsageProvider = (() => {
    try {
      return resolveUsageProviderId(provider);
    } catch {
      return undefined;
    }
  })();
  if (usageProviders.size === 0 && currentUsageProvider) {
    usageProviders.add(currentUsageProvider);
  }
  const usageByProvider = new Map<string, string>();
  let usageSummaryCache: Awaited<ReturnType<typeof loadProviderUsageSummary>> | null | undefined;
  if (usageProviders.size > 0) {
    try {
      usageSummaryCache = await loadProviderUsageSummary({
        timeoutMs: 3500,
        providers: Array.from(usageProviders),
        agentDir: statusAgentDir,
      });
      for (const snapshot of usageSummaryCache.providers) {
        const formatted = formatUsageWindowSummary(snapshot, {
          now: Date.now(),
          maxWindows: 2,
          includeResets: true,
        });
        if (formatted) usageByProvider.set(snapshot.provider, formatted);
      }
    } catch {
      // ignore
    }
  }

  let usageLine: string | null = null;
  try {
    if (oauthProfiles.length === 0 && currentUsageProvider) {
      const summaryLine = usageSummaryCache
        ? formatUsageSummaryLine(usageSummaryCache, { now: Date.now(), maxProviders: 1 })
        : null;
      if (summaryLine) {
        usageLine = summaryLine;
      } else {
        const usage = usageByProvider.get(currentUsageProvider);
        if (usage) usageLine = `📊 Usage: ${usage}`;
      }
    }
  } catch {
    usageLine = null;
  }
  const queueSettings = resolveQueueSettings({
    cfg,
    channel: command.channel,
    sessionEntry,
  });
  const queueKey = sessionKey ?? sessionEntry?.sessionId;
  const queueDepth = queueKey ? getFollowupQueueDepth(queueKey) : 0;
  const queueOverrides = Boolean(
    sessionEntry?.queueDebounceMs ?? sessionEntry?.queueCap ?? sessionEntry?.queueDrop,
  );
  const groupActivation = isGroup
    ? (normalizeGroupActivation(sessionEntry?.groupActivation) ?? defaultGroupActivation())
    : undefined;
  const agentDefaults = cfg.agents?.defaults ?? {};
  const statusText = buildStatusMessage({
    config: cfg,
    agent: {
      ...agentDefaults,
      model: {
        ...agentDefaults.model,
        primary: `${provider}/${model}`,
      },
      contextTokens,
      thinkingDefault: agentDefaults.thinkingDefault,
      verboseDefault: agentDefaults.verboseDefault,
      elevatedDefault: agentDefaults.elevatedDefault,
    },
    sessionEntry,
    sessionKey,
    sessionScope,
    groupActivation,
    resolvedThink: resolvedThinkLevel ?? (await resolveDefaultThinkingLevel()),
    resolvedVerbose: resolvedVerboseLevel,
    resolvedReasoning: resolvedReasoningLevel,
    resolvedElevated: resolvedElevatedLevel,
    modelAuth: resolveModelAuthLabel(provider, cfg, sessionEntry, statusAgentDir),
    usageLine: usageLine ?? undefined,
    queue: {
      mode: queueSettings.mode,
      depth: queueDepth,
      debounceMs: queueSettings.debounceMs,
      cap: queueSettings.cap,
      dropPolicy: queueSettings.dropPolicy,
      showDetails: queueOverrides,
    },
    includeTranscriptUsage: false,
  });

  const authStatusLines = (() => {
    if (oauthProfiles.length === 0) return [];
    const formatStatus = (status: string) => {
      if (status === "ok") return "ok";
      if (status === "static") return "static";
      if (status === "expiring") return "expiring";
      if (status === "missing") return "unknown";
      return "expired";
    };
    const profilesByProvider = new Map<string, typeof oauthProfiles>();
    for (const profile of oauthProfiles) {
      const current = profilesByProvider.get(profile.provider);
      if (current) current.push(profile);
      else profilesByProvider.set(profile.provider, [profile]);
    }
    const lines: string[] = ["OAuth/token status"];
    for (const [provider, profiles] of profilesByProvider) {
      const usageKey = resolveUsageProviderId(provider);
      const usage = usageKey ? usageByProvider.get(usageKey) : undefined;
      const usageSuffix = usage ? ` — usage: ${usage}` : "";
      lines.push(`- ${provider}${usageSuffix}`);
      for (const profile of profiles) {
        const labelText = profile.label || profile.profileId;
        const status = formatStatus(profile.status);
        const expiry =
          profile.status === "static"
            ? ""
            : profile.expiresAt
              ? ` expires in ${formatRemainingShort(profile.remainingMs)}`
              : " expires unknown";
        const source = profile.source !== "store" ? ` (${profile.source})` : "";
        lines.push(`  - ${labelText} ${status}${expiry}${source}`);
      }
    }
    return lines;
  })();

  const fullStatusText =
    authStatusLines.length > 0 ? `${statusText}\n\n${authStatusLines.join("\n")}` : statusText;
  return { text: fullStatusText };
}
