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

/**
 * push-gateway HTTP 客户端（U2 仲裁：豁免 gRPC，走 HTTP /internal/push）。
 *
 * 对齐 02-architecture-design.md §3.2 + §5.3：
 * - POST {PushGatewayUrl}/internal/push
 * - Content-Type: application/json
 * - Body: { parentId, title, content, channels, childId? }
 * - Response: { success: boolean, messageId?: string }
 *
 * Mock 模式（DEV_MODE=true）：不发起真实 HTTP 请求，返回固定成功。
 */
export interface PushPayload {
  parentId: string;
  title: string;
  content: string;
  channels: string[];
  childId?: string;
}

export interface PushResult {
  success: boolean;
  messageId?: string;
  error?: string;
}

export interface PushHttpClient {
  pushViaHttp(payload: PushPayload): Promise<PushResult>;
}

// === Mock 实现（DEV_MODE=true） ===

export class MockPushHttpClient implements PushHttpClient {
  async pushViaHttp(payload: PushPayload): Promise<PushResult> {
    logger.info(
      { parentId: payload.parentId, title: payload.title },
      "[MockPush] push-gateway push simulated",
    );
    eventPushedTotal.inc({
      topic: "internal-push",
      push_status: "success",
    });
    return {
      success: true,
      messageId: `mock-push-${Date.now()}`,
    };
  }
}

// === HTTP 实现（DEV_MODE=false） ===

export class HttpPushHttpClient implements PushHttpClient {
  private readonly baseUrl: string;

  constructor(baseUrl?: string) {
    this.baseUrl = (baseUrl ?? env.PushGatewayUrl).replace(/\/$/, "");
  }

  async pushViaHttp(payload: PushPayload): Promise<PushResult> {
    const url = `${this.baseUrl}/internal/push`;
    const startedAt = Date.now();

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
        signal: AbortSignal.timeout(3000),
      });

      const elapsed = Date.now() - startedAt;
      const status = response.ok ? "success" : "error";

      eventPushedTotal.inc({
        topic: "internal-push",
        push_status: status,
      });

      if (!response.ok) {
        const errorText = await response.text();
        logger.error(
          { url, status: response.status, errorText, elapsed },
          "push-gateway HTTP push failed",
        );
        return {
          success: false,
          error: `HTTP ${response.status}: ${errorText}`,
        };
      }

      const body = (await response.json()) as { messageId?: string };
      logger.info(
        { parentId: payload.parentId, elapsed, messageId: body.messageId },
        "push-gateway HTTP push succeeded",
      );
      return {
        success: true,
        messageId: body.messageId,
      };
    } catch (err) {
      const error = err instanceof Error ? err.message : String(err);
      eventPushedTotal.inc({
        topic: "internal-push",
        push_status: "error",
      });
      logger.error({ url, error }, "push-gateway HTTP push error");
      return { success: false, error };
    }
  }
}

export function createPushHttpClient(): PushHttpClient {
  if (env.DEV_MODE) {
    return new MockPushHttpClient();
  }
  return new HttpPushHttpClient();
}
