// Agent 统一请求封装 — 修复三层重试嵌套问题
// 原 withSessionRetry + withBusinessSessionRetry + chatWithAgent 自带检测 → 统一为单层 withAgentRetry

import Taro from "@tarojs/taro";
import { adminApiRequest, apiRequest } from "./client";

/* ─── 类型定义（保持不变） ─── */

export type AgentModelOption = {
  code: string;
  label: string;
  desc?: string;
  enabled?: boolean;
};

export type AgentActionRequestPayload = {
  actionCode: string;
  targetType?: string;
  targetId?: number;
  payload?: Record<string, unknown>;
  reason?: string;
  conversationId?: number;
};

export type AgentActionSummary = {
  actionRequestId: number;
  actionCode: string;
  status: string;
  riskLevel?: number | string;
  requiresApproval: boolean;
  executionToken?: string | null;
  confirmStep?: number;
  confirmationMode?: string;
  statusDetail?: string;
  retryCount?: number;
  resultSummary?: string;
};

export type AgentToolExecutionResult = {
  actionRequestId: number;
  actionCode: string;
  status: string;
  result?: Record<string, unknown>;
  toolResult?: {
    status?: string;
    summary?: string;
    meta?: Record<string, unknown>;
    error?: Record<string, unknown>;
  };
};

export type AgentConversation = {
  id: number;
  title: string;
  summary: string;
  modelCode?: string;
  updatedAt?: string;
  messageCount?: number;
  summaryCount?: number;
  currentActionRequestId?: number;
  currentPendingToolName?: string;
  currentTaskSummary?: string;
};

export type AgentConversationMessage = {
  id: number;
  role: "user" | "assistant";
  content: string;
  requestId?: string;
  messageIndex?: number;
  createdAt?: string;
  messageType?: string;
  toolName?: string;
  toolStatus?: string;
  displayPayload?: Record<string, unknown>;
  displayPayloadJson?: string;
  display_payload_json?: string;
  token_usage_json?: string;
  message_type?: string;
  tool_name?: string;
  tool_status?: string;
  created_at?: string;
  feedback_rating?: "up" | "down" | "neutral" | "";
  tokenUsageJson?: string;
  modelCode?: string;
  feedbackRating?: "up" | "down" | "neutral" | "";
  feedbackReasonCode?: string;
  feedbackComment?: string;
  feedbackUpdatedAt?: string;
};

export type AgentMessageFeedback = {
  id?: number;
  conversationId?: number;
  messageId?: number;
  rating?: "up" | "down" | "neutral";
  reasonCode?: string;
  comment?: string;
  messagePreview?: string;
  messageIndex?: number;
  retrievalMetaJson?: string;
  sourceSnapshotJson?: string;
  updatedAt?: string;
};

export type AgentEvalRun = {
  id?: number;
  runCode?: string;
  status?: string;
  modelCode?: string;
  promptCode?: string;
  promptVersion?: string;
  promptVersionId?: number;
  promptRuntime?: AgentPromptRuntime;
  totalCount?: number;
  passedCount?: number;
  warningCount?: number;
  failedCount?: number;
  avgScore?: number;
  startedAt?: string;
  finishedAt?: string;
  results?: Record<string, unknown>[];
};

export type AgentPromptRuntime = {
  id?: number;
  promptCode?: string;
  version?: string;
  title?: string;
  source?: string;
  status?: string;
  rolloutMode?: string;
  rolloutPercent?: number;
  modelCode?: string;
  fallbackModelCode?: string;
  guardrail?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
};

export type AgentPromptQualityGate = {
  status?: string;
  reason?: string;
  promptVersionId?: number;
  promptCode?: string;
  promptVersion?: string;
  modelCode?: string;
  evalRunId?: number;
  evalScore?: number;
  evalFailedCount?: number;
  feedbackTotal?: number;
  feedbackDownRate?: number;
  latestEvalRunId?: number;
  latestEvalScore?: number;
  latestEvalFailedCount?: number;
  latestFeedbackTotal?: number;
  latestFeedbackDownRate?: number;
  checkedAt?: string;
  details?: Record<string, unknown>;
};

export type AgentPromptVersion = {
  id?: number;
  promptCode?: string;
  version?: string;
  title?: string;
  status?: string;
  rolloutMode?: string;
  rolloutPercent?: number;
  modelCode?: string;
  fallbackModelCode?: string;
  systemPrompt?: string;
  systemPromptLength?: number;
  systemPromptPreview?: string;
  qualityGate?: AgentPromptQualityGate;
  rollbackCandidateId?: number;
  rollbackCount?: number;
  lastAutoAction?: string;
  lastAutoActionReason?: string;
  lastAutoActionAt?: string;
  guardrail?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
  activatedAt?: string;
  archivedAt?: string;
  createdAt?: string;
  updatedAt?: string;
};

export type AgentPromptRolloutMonitorResult = {
  scannedCount?: number;
  passedCount?: number;
  warningCount?: number;
  failedCount?: number;
  actionCount?: number;
  minCanaryPercent?: number;
  shrinkStepPercent?: number;
  rollbackFull?: boolean;
  actions?: Record<string, unknown>[];
};

export type AgentEvalComparisonRow = {
  promptCode?: string;
  promptVersion?: string;
  promptVersionId?: number;
  modelCode?: string;
  runCount?: number;
  totalCases?: number;
  passedCases?: number;
  warningCases?: number;
  failedCases?: number;
  avgScore?: number;
  latestRunAt?: string;
};

export type AgentOpsOverview = {
  generatedAt?: string;
  window?: Record<string, unknown>;
  health?: {
    status?: "healthy" | "watch" | "critical" | string;
    reasons?: string[];
    summary?: string;
  };
  chat?: Record<string, unknown>;
  feedback?: Record<string, unknown>;
  eval?: Record<string, unknown>;
  prompt?: Record<string, unknown>;
  rollout?: Record<string, unknown>;
  memory?: Record<string, unknown>;
  knowledge?: Record<string, unknown>;
  action?: Record<string, unknown>;
  events?: Record<string, unknown>[];
};

export type AgentOpsAlert = {
  id?: number;
  alertKey?: string;
  severity?: "watch" | "critical" | string;
  status?: "open" | "resolved" | "ignored" | string;
  title?: string;
  detail?: string;
  occurrenceCount?: number;
  notificationCount?: number;
  firstSeenAt?: string;
  lastSeenAt?: string;
  resolvedAt?: string;
  resolveNote?: string;
};

export type AgentOpsAlertCheckResult = {
  trigger?: string;
  healthStatus?: string;
  healthSummary?: string;
  activeAlertCount?: number;
  resolvedCount?: number;
  notifiedCount?: number;
  minimumNotifySeverity?: string;
  alerts?: AgentOpsAlert[];
  openAlerts?: AgentOpsAlert[];
  overview?: AgentOpsOverview;
};

export type AgentReadiness = {
  status?: "ready" | "watch" | "blocked" | string;
  summary?: string;
  generatedAt?: string;
  totals?: Record<string, unknown>;
  dualEntry?: Record<string, unknown>[];
  permission?: Record<string, unknown>[];
  release?: Record<string, unknown>[];
  checks?: Record<string, unknown>[];
};

export type AgentCurrentPrompt = {
  runtime?: AgentPromptRuntime;
  promptCode?: string;
  version?: string;
  title?: string;
  source?: string;
  modelCode?: string;
  fallbackModelCode?: string;
  rolloutMode?: string;
  rolloutPercent?: number;
  systemPrompt?: string;
  systemPromptLength?: number;
};

export type AgentMemory = {
  id: number;
  memoryType: string;
  memoryKey: string;
  memoryText: string;
  confidence?: number;
  status?: string;
  isUserVisible?: boolean;
  forgetReason?: string;
  lastConfirmedAt?: string;
  lastUsedAt?: string;
  usageCount?: number;
  freshnessScore?: number;
  retentionPolicy?: string;
  archivedAt?: string;
  updatedAt?: string;
};

export type AgentActionDetail = {
  id?: number;
  actionCode?: string;
  targetType?: string;
  targetId?: number;
  riskLevel?: number | string;
  requiresApproval?: boolean;
  status?: string;
  reason?: string;
  displayName?: string;
  implementationStatus?: string;
  confirmStep?: number;
  confirmationMode?: string;
  statusDetail?: string;
  retryCount?: number;
  resultSummary?: string;
  actionGroup?: string;
  toolName?: string;
  toolInput?: Record<string, unknown>;
  toolOutput?: Record<string, unknown>;
};

export type AgentGrant = {
  id: number;
  grant_status?: string;
  grantStatus?: string;
  grant_scope_json?: unknown;
  grantScopeJson?: unknown;
  approval_policy_json?: unknown;
  approvalPolicyJson?: unknown;
  auth_method?: string;
  authMethod?: string;
  expires_at?: string;
  expiresAt?: string;
  last_used_at?: string;
  lastUsedAt?: string;
  created_at?: string;
  createdAt?: string;
  updated_at?: string;
  updatedAt?: string;
  client_code?: string;
  clientCode?: string;
  client_name?: string;
  clientName?: string;
  client_type?: string;
  clientType?: string;
  is_official?: boolean;
  isOfficial?: boolean;
};

export type AgentCatalogAction = {
  actionCode: string;
  toolName?: string;
  displayName?: string;
  module?: string;
  moduleCode?: string;
  description?: string;
  riskLevel?: string;
  targetType?: string;
  requiresApproval?: boolean;
  implementationStatus?: string;
  confirmationMode?: string;
  idempotent?: boolean;
  timeoutMs?: number;
  status?: string;
  displayOrder?: number;
  allowedByRole?: boolean;
  availableByRole?: boolean;
  permissionPolicy?: Record<string, unknown>;
  inputSchema?: Record<string, unknown>;
  outputSchema?: Record<string, unknown>;
  requiredFields?: string[];
  active?: boolean;
  runtimeOwned?: boolean;
  executionMode?: string;
  blockedReasons?: string[];
};

export type AgentCatalogDirectory = {
  directory?: Record<string, AgentCatalogAction[]>;
};

export type AgentCapability = AgentCatalogAction & {
  granted?: boolean;
  available?: boolean;
};

export type AgentCapabilityGroups = {
  actingUser?: Record<string, unknown>;
  agentClient?: Record<string, unknown>;
  groups?: Record<string, AgentCapability[]>;
};

export type AgentGrantScopeUpdateResult = {
  id?: number;
  grantStatus?: string;
  allowedActions?: string[];
  removedActions?: string[];
  cancelledPendingActionCount?: number;
};

export type AgentContextMeta = {
  recentMessageCount?: number;
  summaryCount?: number;
  pendingActionCount?: number;
  memoryCount?: number;
  knowledgeCount?: number;
  knowledgeSourceStats?: Record<string, number>;
  contextBudget?: AgentContextBudget;
};

export type AgentContextBudgetSection = {
  section?: string;
  availableItems?: number;
  includedItems?: number;
  skippedItems?: number;
  usedChars?: number;
  truncated?: boolean;
};

export type AgentContextBudget = {
  maxChars?: number;
  usedChars?: number;
  remainingChars?: number;
  truncated?: boolean;
  sections?: AgentContextBudgetSection[];
};

export type AgentConversationContextPreview = {
  conversationId: number;
  query?: string;
  conversation?: AgentConversation | Record<string, unknown>;
  meta?: AgentContextMeta;
  promptRuntime?: AgentPromptRuntime;
  feedbackSummary?: Record<string, unknown>;
  feedback?: AgentMessageFeedback[];
  recentMessages?: Record<string, unknown>[];
  summaries?: Record<string, unknown>[];
  pendingActions?: Record<string, unknown>[];
  memories?: Record<string, unknown>[];
  knowledge?: Record<string, unknown>[];
  sources?: AgentSourceAttribution[];
  promptBlock?: string;
};

export type AgentConversationCompactResult = {
  conversationId: number;
  summaryCount?: number;
  createdSummaries?: Record<string, unknown>[];
  memoryCount?: number;
  createdMemories?: Record<string, unknown>[];
  embeddingCount?: number;
  embeddings?: Record<string, unknown>[];
  conversation?: AgentConversation | Record<string, unknown>;
};

export type AgentSourceAttribution = {
  id?: string | number;
  title?: string;
  snippet?: string;
  sourceType?: string;
  sourceLabel?: string;
  sourceTable?: string;
  retrievalSource?: string;
  rankScore?: string | number;
  updatedAt?: string;
  pageTarget?: string;
};

export type AgentKnowledgeSourceDetail = {
  id?: number;
  title?: string;
  sourceType?: string;
  sourceLabel?: string;
  status?: string;
  summary?: string;
  content?: string;
  contentText?: string;
  fileName?: string;
  tags?: string;
  tagList?: string[];
  scope?: string;
  trustScore?: number;
  trustLevel?: string;
  trustLabel?: string;
  revisionCount?: number;
  verifiedAt?: string;
  lastRevisedAt?: string;
  effectiveDate?: string;
  expireDate?: string;
  createdAt?: string;
  updatedAt?: string;
  contentLength?: number;
};

export type ConsoleKnowledgeSource = {
  id?: number;
  title?: string;
  sourceType?: string;
  source_type?: string;
  status?: string;
  tags?: string;
  trustScore?: number;
  trust_score?: number;
  trustLevel?: string;
  trust_level?: string;
  revisionCount?: number;
  revision_count?: number;
  effectiveDate?: string;
  expireDate?: string;
  verifiedAt?: string;
  lastRevisedAt?: string;
  creator_name?: string;
  created_at?: string;
};

export type ConsoleKnowledgeRevision = {
  id?: number;
  sourceId?: number;
  revisionNo?: number;
  eventType?: string;
  title?: string;
  sourceType?: string;
  status?: string;
  contentHash?: string;
  summary?: string;
  tags?: string;
  trustScore?: number;
  trustLevel?: string;
  changeNote?: string;
  actorUserId?: number;
  actorAdminId?: number;
  snapshotJson?: string;
  createdAt?: string;
};

export type ConsoleKnowledgePage = {
  records?: ConsoleKnowledgeSource[];
  total?: number;
  page?: number;
  pageSize?: number;
};

/* ─── 常量 ─── */

const SESSION_STORAGE_KEY = "official_ai_session_token";
const TOKEN_KEYS = ["xlh_access_token", "elianxin_access_token"];
const AGENT_TIMEOUT_MS = 20000;
const MAX_SESSION_RETRIES = 1; // 最多重试1次bootstrap

const MODEL_DISPLAY_META: Record<string, { label: string; desc: string }> = {
  "qwen-turbo": { label: "Qwen Turbo", desc: "Alibaba Qwen Turbo general assistant model" },
};

/* ─── 工具函数 ─── */

function getAuthToken() {
  for (const key of TOKEN_KEYS) {
    const value = Taro.getStorageSync(key);
    if (value) return String(value);
  }
  return "";
}

const FALLBACK_MODELS: AgentModelOption[] = Object.entries(MODEL_DISPLAY_META).map(
  ([code, meta]) => ({ code, label: meta.label, desc: meta.desc, enabled: true })
);

export function getAgentSessionToken() {
  return Taro.getStorageSync(SESSION_STORAGE_KEY) || "";
}

export function setAgentSessionToken(token: string) {
  if (!token) return;
  Taro.setStorageSync(SESSION_STORAGE_KEY, token);
}

export function clearAgentSessionToken() {
  Taro.removeStorageSync(SESSION_STORAGE_KEY);
}

export function parseJsonLike<T = any>(raw: unknown, fallback: T): T {
  if (raw === null || raw === undefined) return fallback;
  if (typeof raw === "string") {
    try {
      return JSON.parse(raw) as T;
    } catch {
      return fallback;
    }
  }
  if (typeof raw === "object") {
    const wrapper = raw as { value?: unknown };
    if (typeof wrapper.value === "string") {
      try {
        return JSON.parse(wrapper.value) as T;
      } catch {
        return fallback;
      }
    }
    return raw as T;
  }
  return fallback;
}

/** 判断 HTTP 状态码是否为认证失败 */
function isAuthStatus(status: number) {
  return status === 401 || status === 403;
}

/** 判断业务码是否为 agent session 无效 — 精确匹配，不泛化 /session/i */
function isInvalidSessionBizCode(body: any) {
  const code = Number(body?.code ?? 0);
  const msg = String(body?.message || "").toLowerCase();
  return (
    code === 401000 ||
    /invalid\s+agent\s+session/.test(msg) ||
    (/agent\s+session\s+(expired|invalid|not\s*found)/).test(msg)
  );
}

/** 综合判断是否需要重新 bootstrap session */
function needsSessionRecovery(status: number, body: any) {
  if (isAuthStatus(status)) return true;
  if (isInvalidSessionBizCode(body)) return true;
  return false;
}

async function handleAuthFailure(status: number, body: any) {
  if (!isAuthStatus(status)) return;
  const authToken = getAuthToken();
  if (!authToken) {
    Taro.showToast({ title: "请先登录后使用智能助手", icon: "none" });
    await Taro.reLaunch({ url: "/pages/login/index" });
    return;
  }
  // 清掉过期 session token
  if (status === 403 || isInvalidSessionBizCode(body)) {
    clearAgentSessionToken();
  }
}

function buildAgentHeaders(extra?: Record<string, string>, clientRequestId?: string) {
  const authToken = getAuthToken();
  const sessionToken = getAgentSessionToken();
  return {
    "Content-Type": "application/json",
    ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
    ...(sessionToken ? { "X-Agent-Session-Token": sessionToken } : {}),
    ...(clientRequestId ? { "X-Client-Request-Id": clientRequestId } : {}),
    ...(extra || {}),
  };
}

function withTrace(message: string, body: any) {
  const traceId = String(body?.traceId || "").trim();
  return traceId ? `${message} [traceId=${traceId}]` : message;
}

/* ─── 统一请求 + 单层重试 ─── */

async function agentRequest(options: Taro.request.Option): Promise<Taro.request.SuccessCallbackResult<any>> {
  try {
    return await Taro.request({ timeout: AGENT_TIMEOUT_MS, ...options });
  } catch (e) {
    throw new Error(`AGENT_HTTP_FAILED(timeout=${AGENT_TIMEOUT_MS}): ${String((e as Record<string, unknown>)?.errMsg || e)}`);
  }
}

/**
 * 统一 Agent 请求：自动处理 session 过期重试
 * - 只重试一次 bootstrap
 * - 不再做三层嵌套
 * - 返回已校验的 response + body
 */
async function agentRequestWithRetry(
  options: Taro.request.Option,
  clientRequestId?: string
): Promise<{ response: Taro.request.SuccessCallbackResult<any>; body: any }> {
  const headers = buildAgentHeaders(undefined, clientRequestId);
  const fullOptions = { ...options, header: { ...headers, ...(options.header || {}) } };

  let result = await agentRequest(fullOptions);
  let body = result.data as Record<string, unknown>;

  // 判断是否需要 session 恢复
  if (needsSessionRecovery(result.statusCode, body)) {
    clearAgentSessionToken();
    try {
      await bootstrapOfficialSession();
    } catch (bootstrapErr) {
      // bootstrap 失败直接抛出，不继续重试
      await handleAuthFailure(result.statusCode, body);
      throw new Error(
        withTrace(
          `AGENT_SESSION_RECOVERY_FAILED(status=${result.statusCode},code=${body?.code ?? "NA"}): ${String(body?.message || "unknown")}`,
          body
        )
      );
    }
    // 用新 session token 重试一次
    const retryHeaders = buildAgentHeaders(undefined, clientRequestId);
    result = await agentRequest({ ...fullOptions, header: retryHeaders });
    body = result.data as Record<string, unknown>;
  }

  return { response: result, body };
}

/** 对业务返回做统一校验，失败抛错 */
function ensureSuccess(response: Taro.request.SuccessCallbackResult<any>, body: any, label: string) {
  if (response.statusCode !== 200 || !body || body.code !== 0) {
    void handleAuthFailure(response.statusCode, body);
    throw new Error(
      withTrace(
        `${label}(status=${response.statusCode},code=${body?.code ?? "NA"}): ${String(body?.message || "unknown")}`,
        body
      )
    );
  }
}

/* ─── 对外 API（全部走统一封装） ─── */

export async function bootstrapOfficialSession() {
  const data = await apiRequest("/api/agent/official/bootstrap", { method: "POST" });
  const token = String(data?.sessionToken || "");
  setAgentSessionToken(token);
  return data;
}

export async function getGroupedCapabilities(): Promise<AgentCapabilityGroups | null> {
  const sessionToken = getAgentSessionToken();
  if (!sessionToken) return null;

  try {
    const { response, body } = await agentRequestWithRetry({
      url: `${__API_BASE__}/api/agent/me/capabilities/grouped`,
      method: "GET",
    });

    if (response.statusCode !== 200 || !body || body.code !== 0) {
      await handleAuthFailure(response.statusCode, body);
      return null;
    }
    return body.data as AgentCapabilityGroups;
  } catch {
    return null;
  }
}

export async function getAgentCatalog() {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/catalog`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_CATALOG_FAILED");
  return body.data as AgentCatalogDirectory;
}

export async function listAgentGrants() {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/grants`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_GRANTS_FAILED");
  return (body.data || []) as AgentGrant[];
}

export async function updateAgentGrantScope(grantId: number, allowedActions: string[]) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/grants/${grantId}/scope`,
    method: "PUT",
    data: { allowedActions },
  });
  ensureSuccess(response, body, "AGENT_GRANT_SCOPE_UPDATE_FAILED");
  return body.data as AgentGrantScopeUpdateResult;
}

export async function revokeAgentGrant(grantId: number) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/grants/${grantId}/revoke`,
    method: "POST",
  });
  ensureSuccess(response, body, "AGENT_GRANT_REVOKE_FAILED");
}

export async function listAgentPendingSummary() {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/pending-summary`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_PENDING_SUMMARY_FAILED");
  return (body.data || []) as Record<string, unknown>[];
}

export async function listAgentLogSummary() {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/logs/summary`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_LOG_SUMMARY_FAILED");
  return (body.data || []) as Record<string, unknown>[];
}

function normalizeModel(item: any): AgentModelOption | null {
  if (!item || typeof item !== "object") return null;
  const code = String(item.code || item.model || item.id || "").trim();
  if (!code) return null;
  const displayMeta = MODEL_DISPLAY_META[code];
  const label = String(displayMeta?.label || item.label || item.name || code).trim();
  const desc = String(displayMeta?.desc || item.desc || item.description || "").trim();
  return { code, label, desc, enabled: item.enabled !== false };
}

export async function getModelsWithFallback() {
  try {
    const { response, body } = await agentRequestWithRetry({
      url: `${__API_BASE__}/api/agent/models`,
      method: "GET",
    });

    if (response.statusCode === 200 && body?.code === 0) {
      const rows = Array.isArray(body?.data)
        ? body.data
        : Array.isArray(body?.data?.models)
          ? body.data.models
          : [];
      const models = rows.map(normalizeModel).filter(Boolean) as AgentModelOption[];
      if (models.length > 0) return models;
    }
    await handleAuthFailure(response.statusCode, body);
  } catch {
    // silent fallback
  }
  return FALLBACK_MODELS;
}

export async function requestAgentAction(payload: AgentActionRequestPayload, clientRequestId?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/request`,
    method: "POST",
    data: payload,
  }, clientRequestId);
  ensureSuccess(response, body, "AGENT_ACTION_REQUEST_FAILED");
  return body.data as AgentActionSummary;
}

export async function approveAgentAction(actionRequestId: number, comment?: string, second = false) {
  const path = second ? "approve-second" : "approve";
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/${actionRequestId}/${path}`,
    method: "POST",
    data: { comment: comment || "" },
  });
  ensureSuccess(response, body, "AGENT_ACTION_APPROVE_FAILED");
  return body.data as AgentActionSummary;
}

export async function retryAgentAction(actionRequestId: number, comment?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/${actionRequestId}/retry`,
    method: "POST",
    data: { comment: comment || "" },
  });
  ensureSuccess(response, body, "AGENT_ACTION_RETRY_FAILED");
  return body.data as AgentActionSummary;
}

export async function cancelAgentAction(actionRequestId: number, comment?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/${actionRequestId}/cancel`,
    method: "POST",
    data: { comment: comment || "" },
  });
  ensureSuccess(response, body, "AGENT_ACTION_CANCEL_FAILED");
}

export async function rejectAgentAction(actionRequestId: number, comment?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/${actionRequestId}/reject`,
    method: "POST",
    data: { comment: comment || "" },
  });
  ensureSuccess(response, body, "AGENT_ACTION_REJECT_FAILED");
}

export async function getAgentActionDetail(actionRequestId: number) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/${actionRequestId}`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_ACTION_DETAIL_FAILED");
  return body.data as AgentActionDetail;
}

export async function executeAgentAction(actionRequestId: number, executionToken: string, clientRequestId?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/actions/${actionRequestId}/execute`,
    method: "POST",
    data: { executionToken },
  }, clientRequestId);
  ensureSuccess(response, body, "AGENT_ACTION_EXECUTE_FAILED");
  return body.data as AgentToolExecutionResult;
}

export async function listConversations() {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/conversations`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_CONVERSATIONS_FAILED");
  return (body.data || []) as AgentConversation[];
}

export async function createConversation(payload?: { title?: string; model?: string }) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/conversations`,
    method: "POST",
    data: payload || {},
  });
  ensureSuccess(response, body, "AGENT_CREATE_CONVERSATION_FAILED");
  return body.data as AgentConversation;
}

export async function getConversationMessages(conversationId: number, limit = 80, cursor?: number) {
  const query = new URLSearchParams();
  query.set("limit", String(limit));
  if (cursor) query.set("cursor", String(cursor));
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/conversations/${conversationId}/messages?${query.toString()}`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_MESSAGES_FAILED");
  return (body.data || []) as AgentConversationMessage[];
}

export async function previewAgentConversationContext(
  conversationId: number,
  params?: { query?: string; includePromptBlock?: boolean }
) {
  const query = new URLSearchParams();
  if (params?.query) query.set("query", params.query);
  if (typeof params?.includePromptBlock === "boolean") {
    query.set("includePromptBlock", String(params.includePromptBlock));
  }
  const suffix = query.toString() ? `?${query.toString()}` : "";
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/conversations/${conversationId}/context${suffix}`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_CONTEXT_PREVIEW_FAILED");
  return body.data as AgentConversationContextPreview;
}

export async function compactAgentConversation(
  conversationId: number,
  payload?: { model?: string; extractMemories?: boolean }
) {
  const data: Record<string, unknown> = {};
  if (payload?.model) data.model = payload.model;
  if (typeof payload?.extractMemories === "boolean") data.extractMemories = payload.extractMemories;
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/conversations/${conversationId}/compact`,
    method: "POST",
    data,
  });
  ensureSuccess(response, body, "AGENT_CONVERSATION_COMPACT_FAILED");
  return body.data as AgentConversationCompactResult;
}

export async function listAgentMemories(params?: { status?: string; visibleOnly?: boolean; limit?: number }) {
  const query = new URLSearchParams();
  if (params?.status) query.set("status", params.status);
  if (typeof params?.visibleOnly === "boolean") query.set("visibleOnly", String(params.visibleOnly));
  if (params?.limit) query.set("limit", String(params.limit));
  const suffix = query.toString() ? `?${query.toString()}` : "";
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/memories${suffix}`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_MEMORIES_FAILED");
  return (body.data || []) as AgentMemory[];
}

// 🔧 修复：原来这三个函数直接用 Taro.request 跳过了 session 重试
export async function disableAgentMemory(memoryId: number, reason?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/memories/${memoryId}/disable`,
    method: "POST",
    data: { reason: reason || "" },
  });
  ensureSuccess(response, body, "AGENT_MEMORY_DISABLE_FAILED");
}

export async function deleteAgentMemory(memoryId: number, reason?: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/memories/${memoryId}/delete`,
    method: "POST",
    data: { reason: reason || "" },
  });
  ensureSuccess(response, body, "AGENT_MEMORY_DELETE_FAILED");
}

export async function createAgentMemory(text: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/memories`,
    method: "POST",
    data: { text },
  });
  ensureSuccess(response, body, "AGENT_MEMORY_CREATE_FAILED");
  return body;
}

export async function updateAgentMemory(memoryId: number, text: string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/memories/${memoryId}`,
    method: "PUT",
    data: { text },
  });
  ensureSuccess(response, body, "AGENT_MEMORY_UPDATE_FAILED");
  return body;
}

export async function rebuildAgentKnowledgeIndex(limitPerSource?: number) {
  return adminApiRequest("/api/agent/knowledge/reindex", {
    method: "POST",
    data: { limitPerSource },
  }) as Promise<Record<string, unknown>>;
}

export async function listConsoleKnowledgeSources(params?: {
  sourceType?: string;
  status?: string;
  quality?: string;
  page?: number;
  size?: number;
}) {
  const query = new URLSearchParams();
  if (params?.sourceType) query.set("source_type", params.sourceType);
  if (params?.status) query.set("status", params.status);
  if (params?.quality) query.set("quality", params.quality);
  if (params?.page) query.set("page", String(params.page));
  if (params?.size) query.set("size", String(params.size));
  const suffix = query.toString() ? `?${query.toString()}` : "";
  return adminApiRequest(`/api/console/agent/knowledge/list${suffix}`) as Promise<ConsoleKnowledgePage>;
}

export async function updateConsoleKnowledgeStatus(sourceId: number, status: "active" | "draft" | string) {
  return adminApiRequest(`/api/console/agent/knowledge/${sourceId}/status`, {
    method: "PUT",
    data: { status },
  }) as Promise<ConsoleKnowledgeSource>;
}

export async function updateConsoleKnowledgeTrust(sourceId: number, payload: {
  trustScore: number;
  trustLevel: "low" | "standard" | "verified" | "official" | string;
  note?: string;
}) {
  return adminApiRequest(`/api/console/agent/knowledge/${sourceId}/trust`, {
    method: "PUT",
    data: payload,
  }) as Promise<ConsoleKnowledgeSource>;
}

export async function listConsoleKnowledgeRevisions(sourceId: number, limit = 20) {
  return adminApiRequest(
    `/api/console/agent/knowledge/${sourceId}/revisions?limit=${encodeURIComponent(String(limit))}`
  ) as Promise<ConsoleKnowledgeRevision[]>;
}

export async function reindexConsoleKnowledge() {
  return adminApiRequest("/api/console/agent/knowledge/reindex", {
    method: "POST",
    data: {},
  }) as Promise<Record<string, unknown>>;
}

export async function getAgentKnowledgeSourceDetail(sourceId: number | string) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/knowledge/sources/${encodeURIComponent(String(sourceId))}`,
    method: "GET",
  });
  ensureSuccess(response, body, "AGENT_KNOWLEDGE_SOURCE_DETAIL_FAILED");
  return body.data as AgentKnowledgeSourceDetail;
}

export async function submitAgentMessageFeedback(conversationId: number, messageId: number, payload: {
  rating: "up" | "down" | "neutral";
  reasonCode?: string;
  comment?: string;
}) {
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/conversations/${conversationId}/messages/${messageId}/feedback`,
    method: "POST",
    data: payload,
  });
  ensureSuccess(response, body, "AGENT_MESSAGE_FEEDBACK_FAILED");
  return body.data as AgentMessageFeedback;
}

export async function getAgentEvalSummary() {
  return adminApiRequest("/api/agent/evals/summary") as Promise<Record<string, unknown>>;
}

export async function getAgentOpsOverview() {
  return adminApiRequest("/api/agent/ops/overview") as Promise<AgentOpsOverview>;
}

export async function getAgentReadiness() {
  return adminApiRequest("/api/agent/ops/readiness") as Promise<AgentReadiness>;
}

export async function listAgentOpsAlerts(params?: { status?: string; limit?: number }) {
  const query = new URLSearchParams();
  if (params?.status) query.set("status", params.status);
  if (params?.limit) query.set("limit", String(params.limit));
  const suffix = query.toString() ? `?${query.toString()}` : "";
  return adminApiRequest(`/api/agent/ops/alerts${suffix}`) as Promise<AgentOpsAlert[]>;
}

export async function checkAgentOpsAlerts(payload?: {
  notifyAdmins?: boolean;
  resolveHealthy?: boolean;
  minimumNotifySeverity?: "watch" | "critical" | string;
}) {
  return adminApiRequest("/api/agent/ops/check-alerts", {
    method: "POST",
    data: payload || {},
  }) as Promise<AgentOpsAlertCheckResult>;
}

export async function resolveAgentOpsAlert(alertId: number, note?: string) {
  return adminApiRequest(`/api/agent/ops/alerts/${alertId}/resolve`, {
    method: "POST",
    data: { note: note || "" },
  }) as Promise<AgentOpsAlert>;
}

export async function getAgentEvalComparison(params?: {
  promptCode?: string;
  days?: number;
  limit?: number;
}) {
  const query = new URLSearchParams();
  if (params?.promptCode) query.set("promptCode", params.promptCode);
  if (params?.days) query.set("days", String(params.days));
  if (params?.limit) query.set("limit", String(params.limit));
  const suffix = query.toString() ? `?${query.toString()}` : "";
  return adminApiRequest(`/api/agent/evals/comparison${suffix}`) as Promise<AgentEvalComparisonRow[]>;
}

export async function listAgentEvalRuns(limit = 10) {
  return adminApiRequest(`/api/agent/evals/runs?limit=${encodeURIComponent(String(limit))}`) as Promise<AgentEvalRun[]>;
}

export async function runAgentEval(payload?: {
  model?: string;
  caseCodes?: string[];
  limit?: number;
}) {
  return adminApiRequest("/api/agent/evals/run", {
    method: "POST",
    data: payload || {},
  }) as Promise<AgentEvalRun>;
}

export async function getAgentCurrentPrompt(params?: { promptCode?: string; model?: string }) {
  const query = new URLSearchParams();
  if (params?.promptCode) query.set("promptCode", params.promptCode);
  if (params?.model) query.set("model", params.model);
  const suffix = query.toString() ? `?${query.toString()}` : "";
  return adminApiRequest(`/api/agent/prompts/current${suffix}`) as Promise<AgentCurrentPrompt>;
}

export async function listAgentPromptVersions(params?: {
  promptCode?: string;
  status?: string;
  limit?: number;
}) {
  const query = new URLSearchParams();
  if (params?.promptCode) query.set("promptCode", params.promptCode);
  if (params?.status) query.set("status", params.status);
  if (params?.limit) query.set("limit", String(params.limit));
  const suffix = query.toString() ? `?${query.toString()}` : "";
  return adminApiRequest(`/api/agent/prompts${suffix}`) as Promise<AgentPromptVersion[]>;
}

export async function createAgentPromptVersion(payload: {
  promptCode?: string;
  version: string;
  title?: string;
  systemPrompt: string;
  modelCode?: string;
  fallbackModelCode?: string;
  rolloutMode?: string;
  rolloutPercent?: number;
  guardrail?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
}) {
  return adminApiRequest("/api/agent/prompts", {
    method: "POST",
    data: payload,
  }) as Promise<AgentPromptVersion>;
}

export async function activateAgentPromptVersion(promptVersionId: number, payload?: {
  rolloutMode?: string;
  rolloutPercent?: number;
}) {
  return adminApiRequest(`/api/agent/prompts/${promptVersionId}/activate`, {
    method: "POST",
    data: payload || {},
  }) as Promise<AgentPromptVersion>;
}

export async function archiveAgentPromptVersion(promptVersionId: number) {
  return adminApiRequest(`/api/agent/prompts/${promptVersionId}/archive`, {
    method: "POST",
    data: {},
  }) as Promise<AgentPromptVersion>;
}

export async function checkAgentPromptQualityGate(promptVersionId: number) {
  return adminApiRequest(`/api/agent/prompts/${promptVersionId}/quality-gate`, {
    method: "POST",
    data: {},
  }) as Promise<AgentPromptQualityGate>;
}

export async function monitorAgentPromptRollouts(payload?: {
  limit?: number;
  minCanaryPercent?: number;
  shrinkStepPercent?: number;
  rollbackFull?: boolean;
}) {
  return adminApiRequest("/api/agent/prompts/monitor-rollouts", {
    method: "POST",
    data: payload || {},
  }) as Promise<AgentPromptRolloutMonitorResult>;
}

export async function chatWithAgent(payload: {
  conversationId?: number;
  model?: string;
  messages: Array<{ role: "user" | "assistant" | "system"; content: string }>;
}, clientRequestId?: string) {
  // 🔧 修复：不再有额外的第三层重试，统一走 agentRequestWithRetry
  const { response, body } = await agentRequestWithRetry({
    url: `${__API_BASE__}/api/agent/chat`,
    method: "POST",
    data: payload,
  }, clientRequestId);

  ensureSuccess(response, body, "AGENT_CHAT_FAILED");
  return body.data as {
    reply: string;
    model?: string;
    error?: string;
    conversationId?: number;
    conversation?: AgentConversation;
    assistantMessage?: AgentConversationMessage;
    promptRuntime?: AgentPromptRuntime;
    retrieval?: Record<string, unknown>;
    metrics?: {
      elapsedMs?: number;
      llmSuccess?: boolean;
      llmFallback?: boolean;
      hasKnowledge?: boolean;
      hasPendingActions?: boolean;
      knowledgeCount?: number;
      memoryCount?: number;
      sourceCount?: number;
      knowledgeSourceStats?: Record<string, number>;
    };
    sources?: AgentSourceAttribution[];
  };
}
