async function adminFetch<T>(path: string, init?: RequestInit): Promise<T> {
  const response = await fetch(path, {
    ...init,
    credentials: 'include',
    headers: {
      Accept: 'application/json',
      ...(init?.body ? { 'Content-Type': 'application/json' } : {}),
      ...(init?.headers ?? {}),
    },
  });
  const payload = (await response.json().catch(() => ({}))) as {
    data?: T;
    message?: string;
    error?: { code: string; message: string };
  };
  if (!response.ok) {
    throw new Error(payload?.error?.message ?? payload?.message ?? `请求失败 (${response.status})`);
  }
  return (payload.data !== undefined ? payload.data : payload) as T;
}

export type AdminUser = {
  id: string;
  username: string;
  slug: string;
  email: string;
  displayName: string;
  role: string;
  status: string;
  balanceCents: number;
  createdAt: string;
};

export type AdminSummary = {
  totalUsers: number;
  activeUsers: number;
  totalBalanceCents: number;
  llm?: {
    keyCount: number;
    selectedKeyName: string | null;
    globalModel: string | null;
  };
};

export type LedgerEntry = {
  id: string;
  userId: string;
  username?: string;
  type: string;
  amountCents: number;
  note: string;
  createdAt: string;
};

export type UsageRecord = {
  id: string;
  userId: string;
  username?: string;
  provider: string;
  model: string;
  inputTokens: number;
  outputTokens: number;
  costCents: number;
  createdAt: string;
};

export type WechatAdminSummary = {
  config: {
    mpEnabled: boolean;
    scheduleEnabled: boolean;
    reminderWorkerEnabled: boolean;
    appId: string | null;
    publicBaseUrl: string | null;
    bindPath: string | null;
    tokenEndpointConfigured: boolean;
    customerServiceEndpointConfigured: boolean;
  };
  counts: {
    boundUsers: number;
    routes: { total: number; active: number };
    recentMessages: Record<string, number>;
    digests: Record<string, number>;
    recentDeliveries: Record<string, number>;
  };
};

export type WechatBinding = {
  userId: string;
  username: string;
  displayName: string;
  status: string;
  appId: string | null;
  openidMasked: string;
  nickname: string | null;
  avatarUrl: string | null;
  lastLoginAt: number;
  boundAt: number;
  routeId: string | null;
  routeStatus: string | null;
  agentSessionId: string | null;
  routeUpdatedAt: number | null;
};

export type WechatMessage = {
  appId: string | null;
  openidMasked: string;
  msgId: string;
  status: string;
  agentSessionId: string | null;
  createdAt: number;
  updatedAt: number;
  userId: string | null;
  username: string | null;
  displayName: string | null;
};

export type WechatDigestSubscription = {
  id: string;
  userId: string;
  username: string;
  displayName: string;
  digestType: string;
  hour: number;
  minute: number;
  timezone: string;
  channel: string;
  status: string;
  nextRunAt: number;
  lastRunAt: number | null;
  attempts: number;
  lastError: string | null;
  sourceText: string | null;
  createdAt: number;
  updatedAt: number;
};

export type WechatDeliveryLog = {
  id: string;
  reminderId: string | null;
  subscriptionId: string | null;
  userId: string;
  username: string;
  displayName: string;
  channel: string;
  status: string;
  providerMessageId: string | null;
  errorCode: string | null;
  errorMessage: string | null;
  createdAt: number;
  digestType: string | null;
};

export type WechatWebNotification = {
  id: string;
  userId: string;
  username: string;
  displayName: string;
  channel: string;
  notificationType: string;
  title: string;
  body: string;
  status: string;
  readAt: number | null;
  createdAt: number;
  updatedAt: number;
};

export type CreateWechatNotificationPayload = {
  userId?: string;
  userIds?: string[];
  audience?: 'all';
  allUsers?: boolean;
  title: string;
  body: string;
  notificationType?: string;
  channel?: 'web' | 'wechat';
  channels?: Array<'web' | 'wechat'>;
};

// ─── Summary ──────────────────────────────────────────────────────────────────

export async function fetchAdminSummary() {
  return adminFetch<{ summary: AdminSummary }>('/admin-api/summary');
}

// ─── Users ────────────────────────────────────────────────────────────────────

export async function fetchAdminUsers(params: {
  page?: number;
  pageSize?: number;
  search?: string;
  role?: string;
  status?: string;
}) {
  const q = new URLSearchParams();
  if (params.page) q.set('page', String(params.page));
  if (params.pageSize) q.set('pageSize', String(params.pageSize));
  if (params.search) q.set('search', params.search);
  if (params.role) q.set('role', params.role);
  if (params.status) q.set('status', params.status);
  return adminFetch<{ users: AdminUser[]; total: number; page: number; pageSize: number; totalPages: number }>(
    `/admin-api/users?${q}`,
  );
}

export async function createAdminUser(body: {
  username: string;
  password: string;
  displayName?: string;
  role?: string;
}) {
  return adminFetch<{ user: AdminUser }>('/admin-api/users', {
    method: 'POST',
    body: JSON.stringify(body),
  });
}

export async function patchAdminUser(
  userId: string,
  patch: { role?: string; status?: string; displayName?: string; password?: string },
) {
  return adminFetch<{ user: AdminUser }>(`/admin-api/users/${userId}`, {
    method: 'PATCH',
    body: JSON.stringify(patch),
  });
}

export async function rechargeUser(userId: string, amountCents: number, note = '') {
  return adminFetch<{ user: AdminUser }>(`/admin-api/users/${userId}/recharge`, {
    method: 'POST',
    body: JSON.stringify({ amountCents, note }),
  });
}

// ─── Billing ──────────────────────────────────────────────────────────────────

export async function fetchAdminLedger(params: { page?: number; pageSize?: number } = {}) {
  const q = new URLSearchParams();
  if (params.page) q.set('page', String(params.page));
  if (params.pageSize) q.set('pageSize', String(params.pageSize));
  return adminFetch<{ entries: LedgerEntry[]; total: number; page: number; totalPages: number }>(
    `/admin-api/ledger?${q}`,
  );
}

export async function fetchAdminUsage(params: { page?: number; pageSize?: number } = {}) {
  const q = new URLSearchParams();
  if (params.page) q.set('page', String(params.page));
  if (params.pageSize) q.set('pageSize', String(params.pageSize));
  return adminFetch<{ records: UsageRecord[]; total: number; page: number; totalPages: number }>(
    `/admin-api/usage?${q}`,
  );
}

// ─── WeChat MP ────────────────────────────────────────────────────────────────

export async function fetchWechatSummary() {
  return adminFetch<WechatAdminSummary>('/admin-api/wechat/summary');
}

export async function fetchWechatBindings(params: { search?: string; limit?: number } = {}) {
  const q = new URLSearchParams();
  if (params.search) q.set('search', params.search);
  if (params.limit) q.set('limit', String(params.limit));
  return adminFetch<{ bindings: WechatBinding[] }>(`/admin-api/wechat/bindings?${q}`);
}

export async function fetchWechatMessages(params: { status?: string; limit?: number } = {}) {
  const q = new URLSearchParams();
  if (params.status) q.set('status', params.status);
  if (params.limit) q.set('limit', String(params.limit));
  return adminFetch<{ messages: WechatMessage[] }>(`/admin-api/wechat/messages?${q}`);
}

export async function fetchWechatDigests(params: { status?: string; limit?: number } = {}) {
  const q = new URLSearchParams();
  if (params.status) q.set('status', params.status);
  if (params.limit) q.set('limit', String(params.limit));
  return adminFetch<{ digests: WechatDigestSubscription[] }>(`/admin-api/wechat/digests?${q}`);
}

export async function fetchWechatDeliveries(params: { status?: string; limit?: number } = {}) {
  const q = new URLSearchParams();
  if (params.status) q.set('status', params.status);
  if (params.limit) q.set('limit', String(params.limit));
  return adminFetch<{ deliveries: WechatDeliveryLog[] }>(`/admin-api/wechat/deliveries?${q}`);
}

export async function fetchWechatWebNotifications(params: { status?: string; limit?: number } = {}) {
  const q = new URLSearchParams();
  if (params.status) q.set('status', params.status);
  if (params.limit) q.set('limit', String(params.limit));
  return adminFetch<{ notifications: WechatWebNotification[] }>(
    `/admin-api/wechat/web-notifications?${q}`,
  );
}

export async function createWechatWebNotification(body: CreateWechatNotificationPayload) {
  return adminFetch<{
    ok: boolean;
    created: number;
    wechatSent: number;
    wechatFailures: Array<{ userId: string; message: string }>;
    targets: number;
  }>('/admin-api/wechat/web-notifications', {
    method: 'POST',
    body: JSON.stringify(body),
  });
}

export async function clearWechatRoute(userId: string) {
  return adminFetch<{ ok: boolean; deleted: number; openidMasked: string }>(
    `/admin-api/wechat/users/${userId}/route/clear`,
    { method: 'POST' },
  );
}

export async function cancelWechatDigest(id: string) {
  return adminFetch<{ ok: boolean }>(`/admin-api/wechat/digests/${id}/cancel`, { method: 'POST' });
}

export async function resumeWechatDigest(id: string) {
  return adminFetch<{ ok: boolean; nextRunAt: number }>(`/admin-api/wechat/digests/${id}/resume`, {
    method: 'POST',
  });
}
