import { env } from "../../config/env.js";
import { logger } from "../observability/logger.js";

/**
 * Push Gateway HTTP 客户端。
 *
 * 仲裁依据：
 * - M4：HTTP POST /internal/push（豁免 gRPC）
 * - PushGateway 软失败：不可用时返回 false，不阻断主流程
 * - 鉴权头：X-Internal-Key = PUSH_INTERNAL_TOKEN
 *
 * 请求体对齐 push-gateway handler.go PushHandler：
 * { userId, event, data }
 */

export interface PushRequest {
  userId: string;
  event: string;
  data: Record<string, unknown>;
}

export interface PushResult {
  sent: boolean;
  error?: string;
}

/**
 * 向 push-gateway 发送实时推送。
 *
 * 软失败语义：
 * - PUSH_GATEWAY_URL 未配置 → 返回 { sent: false }，不报错
 * - 网络错误/非 2xx → 返回 { sent: false, error }，logger.warn
 * - 成功 → 返回 { sent: true }
 */
export async function sendPush(req: PushRequest): Promise<PushResult> {
  if (!env.PUSH_GATEWAY_URL) {
    return { sent: false };
  }

  const url = `${env.PUSH_GATEWAY_URL}/internal/push`;
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };
  if (env.PUSH_INTERNAL_TOKEN) {
    headers["X-Internal-Key"] = env.PUSH_INTERNAL_TOKEN;
  }

  try {
    const res = await fetch(url, {
      method: "POST",
      headers,
      body: JSON.stringify({
        userId: req.userId,
        event: req.event,
        data: req.data,
      }),
    });
    if (!res.ok) {
      const error = `push-gateway returned ${res.status}`;
      logger.warn({ status: res.status, userId: req.userId }, error);
      return { sent: false, error };
    }
    return { sent: true };
  } catch (err) {
    const error = err instanceof Error ? err.message : String(err);
    logger.warn({ err, userId: req.userId }, "Push gateway unavailable");
    return { sent: false, error };
  }
}

/**
 * 批量推送（逐条发送，push-gateway 无批量 API）。
 * 任一失败不影响其他，返回每条结果。
 */
export async function sendPushBatch(
  requests: PushRequest[],
): Promise<PushResult[]> {
  const results: PushResult[] = [];
  for (const req of requests) {
    results.push(await sendPush(req));
  }
  return results;
}

/**
 * 健康检查：探测 push-gateway /readyz。
 * 软失败：不可用返回 false，不阻断 /readyz（仲裁 M2）。
 */
export async function checkPushGateway(): Promise<boolean> {
  if (!env.PUSH_GATEWAY_URL) return false;
  try {
    const res = await fetch(`${env.PUSH_GATEWAY_URL}/readyz`, {
      signal: AbortSignal.timeout(2000),
    });
    return res.ok;
  } catch {
    return false;
  }
}
