/**
 * NomGap backend client — typed HTTP wrappers for the nomgap-backend (port 4013).
 *
 * Auth: Bearer token from the caller's JWT (same JWT_SECRET as platform-service).
 */

import { config } from './config.js';

export interface NomGapClientOptions {
  token?: string;
  requestId?: string;
  productId?: string;
}

async function nomgapFetch<T>(
  path: string,
  init: RequestInit,
  opts: NomGapClientOptions
): Promise<T> {
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(opts.token ? { Authorization: `Bearer ${opts.token}` } : {}),
    ...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
    ...(opts.productId ? { 'x-product-id': opts.productId } : { 'x-product-id': 'nomgap' }),
  };
  const res = await fetch(`${config.NOMGAP_BACKEND_URL}/api${path}`, {
    ...init,
    headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
    signal: AbortSignal.timeout(15_000),
  });
  if (!res.ok) {
    const body = await res.text().catch(() => '');
    throw new Error(`nomgap-backend ${init.method ?? 'GET'} ${path} → ${res.status}: ${body}`);
  }
  return res.json() as Promise<T>;
}

// ── Fasting sessions ───────────────────────────────────────────────────────

export interface FastingSessionDoc {
  id: string;
  userId: string;
  productId: string;
  protocolId: string;
  startedAt: number;
  targetDurationMs: number;
  status: 'active' | 'completed' | 'broken';
  stages: unknown[];
  moodCheckins: unknown[];
  waterIntake: unknown[];
  metrics: {
    actualDurationMs: number;
    completionRatio: number;
    peakAutophagyConfidence: number;
    totalPausedMs: number;
    moodCheckinCount: number;
    averageEnergy: number | null;
    averageMood: number | null;
  };
  createdAt: string;
  updatedAt: string;
}

export function nomgapFastingCreateSession(
  input: { protocolId: string; variables?: Record<string, string> },
  opts: NomGapClientOptions
): Promise<FastingSessionDoc> {
  return nomgapFetch('/fasting/sessions', { method: 'POST', body: JSON.stringify(input) }, opts);
}

export function nomgapFastingSessionsList(
  params: { limit?: number; offset?: number; status?: string; from?: string; to?: string },
  opts: NomGapClientOptions
): Promise<{ items: FastingSessionDoc[]; total: number }> {
  const qs = new URLSearchParams();
  if (params.limit !== undefined) qs.set('limit', String(params.limit));
  if (params.offset !== undefined) qs.set('offset', String(params.offset));
  if (params.status) qs.set('status', params.status);
  if (params.from) qs.set('from', params.from);
  if (params.to) qs.set('to', params.to);
  const q = qs.toString();
  return nomgapFetch(`/fasting/sessions${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

export function nomgapFastingSessionGet(
  sessionId: string,
  opts: NomGapClientOptions
): Promise<FastingSessionDoc> {
  return nomgapFetch(`/fasting/sessions/${sessionId}`, { method: 'GET' }, opts);
}

export function nomgapFastingGetStats(opts: NomGapClientOptions): Promise<Record<string, unknown>> {
  return nomgapFetch('/fasting/stats', { method: 'GET' }, opts);
}

export function nomgapFastingGetWeeklyStats(
  opts: NomGapClientOptions
): Promise<Record<string, unknown>> {
  return nomgapFetch('/fasting/stats/weekly', { method: 'GET' }, opts);
}

// ── Protocols ─────────────────────────────────────────────────────────────

export function nomgapProtocolsList(
  opts: NomGapClientOptions
): Promise<{ protocols: unknown[]; total: number }> {
  return nomgapFetch('/fasting/protocols', { method: 'GET' }, opts);
}

export function nomgapProtocolGet(
  protocolId: string,
  opts: NomGapClientOptions
): Promise<Record<string, unknown>> {
  return nomgapFetch(`/fasting/protocols/${protocolId}`, { method: 'GET' }, opts);
}

// ── Body stages (public — no auth required) ────────────────────────────────

export function nomgapBodyStagesList(
  opts: Pick<NomGapClientOptions, 'requestId'>
): Promise<{ stages: unknown[]; total: number }> {
  return nomgapFetch('/fasting/stages', { method: 'GET' }, opts);
}

// ── Autophagy confidence ──────────────────────────────────────────────────

export interface AutophagyConfidenceInput {
  durationHours: number;
  activityLevel: 'sedentary' | 'light' | 'moderate' | 'active' | 'very_active';
  lastMealCarbs?: number;
  sleepHours?: number;
  completionHistory?: { totalFasts: number; completionRate: number };
  hrvData?: { restingHR?: number; hrv?: number };
}

export interface AutophagyConfidenceResult {
  confidence: number;
  label: 'unlikely' | 'possible' | 'likely' | 'very_likely' | 'near_certain';
  breakdown: {
    duration: number;
    meal: number;
    activity: number;
    sleep: number;
    history: number;
    hrv: number;
  };
  currentStage: string;
}

export function nomgapAutophagyConfidence(
  input: AutophagyConfidenceInput,
  opts: Pick<NomGapClientOptions, 'requestId'>
): Promise<AutophagyConfidenceResult> {
  return nomgapFetch(
    '/fasting/autophagy-confidence',
    { method: 'POST', body: JSON.stringify(input) },
    opts
  );
}

// ── Push triggers ──────────────────────────────────────────────────────────

export type PushTriggerType =
  | 'streak_risk'
  | 'fast_milestone'
  | 'stage_transition'
  | 'social_invite'
  | 'weekly_digest'
  | 'achievement_unlocked'
  | 'refeeding_reminder'
  | 'electrolyte_reminder'
  | 'extended_fast_warning';

export interface PushTriggerDoc {
  id: string;
  productId: string;
  type: PushTriggerType;
  userId: string;
  variables: Record<string, string>;
  status: 'pending' | 'sent' | 'skipped' | 'failed';
  scheduledAt: string;
  createdAt: string;
}

// ── Social fasting ────────────────────────────────────────────────────────

export interface GroupFastDoc {
  id: string;
  userId: string;
  productId: string;
  sessionId: string;
  memberCount: number;
  status: 'active' | 'completed' | 'cancelled';
  createdAt: string;
}

export function nomgapSocialListGroupFasts(
  params: { limit?: number; offset?: number },
  opts: NomGapClientOptions
): Promise<{ items: GroupFastDoc[]; total: number }> {
  const qs = new URLSearchParams();
  if (params.limit !== undefined) qs.set('limit', String(params.limit));
  if (params.offset !== undefined) qs.set('offset', String(params.offset));
  const q = qs.toString();
  return nomgapFetch(`/social/group-fasts${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

export function nomgapPushFire(
  input: {
    type: PushTriggerType;
    userId: string;
    variables?: Record<string, string>;
    scheduledFor?: string;
  },
  opts: NomGapClientOptions
): Promise<PushTriggerDoc> {
  return nomgapFetch('/push-triggers', { method: 'POST', body: JSON.stringify(input) }, opts);
}

export function nomgapPushGetStats(opts: NomGapClientOptions): Promise<Record<string, unknown>> {
  return nomgapFetch('/push-triggers/stats', { method: 'GET' }, opts);
}

export function nomgapPushGetPending(opts: NomGapClientOptions): Promise<PushTriggerDoc[]> {
  return nomgapFetch('/push-triggers/pending', { method: 'GET' }, opts);
}
