/**
 * REST client for platform-service endpoints.
 *
 * Used by the flush scheduler to forward audit events, telemetry,
 * budget/usage records, and poll feature flags from platform-service.
 */

import { config } from './config.js';
import { PRODUCT_ID } from './product-config.js';

const baseUrl = () => config.PLATFORM_SERVICE_URL;

interface FetchOptions {
  method: 'GET' | 'POST';
  path: string;
  body?: unknown;
  headers?: Record<string, string>;
}

async function request<T = unknown>(opts: FetchOptions): Promise<T> {
  const url = `${baseUrl()}${opts.path}`;
  const res = await fetch(url, {
    method: opts.method,
    headers: {
      'Content-Type': 'application/json',
      'x-product-id': PRODUCT_ID,
      ...opts.headers,
    },
    body: opts.body ? JSON.stringify(opts.body) : undefined,
  });

  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(
      `platform-service ${opts.method} ${opts.path} → ${res.status}: ${text.slice(0, 200)}`
    );
  }

  return res.json() as Promise<T>;
}

// ── Audit ──────────────────────────────────────────────────────

export interface AuditEntry {
  userId: string;
  action: string;
  category?: string;
  timestamp?: string;
  details?: Record<string, unknown>;
}

/** POST /audit — fire-and-forget audit write. Returns { accepted: true }. */
export async function postAuditEvents(
  entries: AuditEntry[]
): Promise<{ posted: number; errors: number }> {
  let posted = 0;
  let errors = 0;
  for (const entry of entries) {
    try {
      await request({ method: 'POST', path: '/audit', body: entry });
      posted++;
    } catch {
      errors++;
    }
  }
  return { posted, errors };
}

// ── Telemetry ──────────────────────────────────────────────────

export interface TelemetryEvent {
  id: string;
  name: string;
  timestamp: string;
  properties?: Record<string, unknown>;
  [key: string]: unknown;
}

/** POST /telemetry/events — batch ingest telemetry events. */
export async function postTelemetryEvents(
  events: TelemetryEvent[]
): Promise<{ accepted: number; rejected: number }> {
  if (events.length === 0) return { accepted: 0, rejected: 0 };
  return request<{ accepted: number; rejected: number }>({
    method: 'POST',
    path: '/telemetry/events',
    body: { productId: PRODUCT_ID, events },
  });
}

// ── Usage / Budget ─────────────────────────────────────────────

export interface UsageRecord {
  userId: string;
  date: string;
  model?: string;
  source?: string;
  inputTokens?: number;
  outputTokens?: number;
  costUsd?: number;
  requestCount?: number;
}

/** POST /usage — upsert usage record. */
export async function postUsageRecord(record: UsageRecord): Promise<unknown> {
  return request({ method: 'POST', path: '/usage', body: record });
}

/** Post multiple usage records (budget flush). */
export async function postUsageRecords(
  records: UsageRecord[]
): Promise<{ posted: number; errors: number }> {
  let posted = 0;
  let errors = 0;
  for (const record of records) {
    try {
      await postUsageRecord(record);
      posted++;
    } catch {
      errors++;
    }
  }
  return { posted, errors };
}

// ── Feature Flags ──────────────────────────────────────────────

/** GET /flags/poll — poll current flag values for this product. */
export async function pollFlags(
  platform?: string
): Promise<{ flags: Record<string, boolean>; productId: string }> {
  const params = new URLSearchParams();
  if (platform) params.set('platform', platform);
  const qs = params.toString();
  return request<{ flags: Record<string, boolean>; productId: string }>({
    method: 'GET',
    path: `/flags/poll${qs ? `?${qs}` : ''}`,
  });
}
