/**
 * MindLyst backend client — typed HTTP wrappers for the mindlyst-backend (port 4014).
 *
 * Auth: Bearer token from the caller's JWT (same JWT_SECRET as platform-service).
 * Admin callers may pass x-admin-user-id to operate on behalf of any user.
 */

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

export interface MindlystClientOptions {
  token?: string;
  requestId?: string;
  /** When set (admin only) — overrides the JWT sub used as userId in backend routes */
  adminUserId?: string;
}

// ── Shared fetch helper ────────────────────────────────────────────────────

async function mindlystFetch<T>(
  path: string,
  init: RequestInit,
  opts: MindlystClientOptions
): 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.adminUserId ? { 'x-admin-user-id': opts.adminUserId } : {}),
  };
  const res = await fetch(`${config.MINDLYST_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(`mindlyst-backend ${init.method ?? 'GET'} ${path} → ${res.status}: ${body}`);
  }
  return res.json() as Promise<T>;
}

// ── Memory items ───────────────────────────────────────────────────────────

export interface MemoryItemDoc {
  id: string;
  productId: string;
  userId: string;
  sourceType: string;
  captureSurface: string;
  rawContent: string;
  triageResult: {
    contentType: string;
    summary?: string;
    urgencyScore: number;
    emotionScore: number;
    confidenceScore: number;
    suggestedBrainId: string;
    entities: string[];
    suggestedActions: string[];
  };
  brainIds: string[];
  actedOn: boolean;
  actedOnAt: string | null;
  nudgeCount: number;
  reminderAt?: string;
  isSensitive: boolean;
  createdAt: string;
  updatedAt: string;
}

export function mindlystMemoryList(
  params: {
    brainId?: string;
    filter?: 'forgotten' | 'completed_today';
    limit?: number;
    offset?: number;
    productId?: string;
  },
  opts: MindlystClientOptions
): Promise<{ items: MemoryItemDoc[]; limit: number; offset: number }> {
  const qs = new URLSearchParams();
  if (params.brainId) qs.set('brainId', params.brainId);
  if (params.filter) qs.set('filter', params.filter);
  if (params.limit !== undefined) qs.set('limit', String(params.limit));
  if (params.offset !== undefined) qs.set('offset', String(params.offset));
  if (params.productId) qs.set('productId', params.productId);
  const q = qs.toString();
  return mindlystFetch(`/memory-items${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

export function mindlystMemoryGetItem(
  itemId: string,
  opts: MindlystClientOptions
): Promise<MemoryItemDoc> {
  return mindlystFetch(`/memory-items/${itemId}`, { method: 'GET' }, opts);
}

export function mindlystMemoryRetriage(
  itemId: string,
  opts: MindlystClientOptions
): Promise<MemoryItemDoc> {
  return mindlystFetch(`/memory-items/${itemId}/retriage`, { method: 'POST' }, opts);
}

export function mindlystMemoryPatch(
  itemId: string,
  action: 'mark_done' | 'mark_undone' | 'increment_nudge' | 'set_reminder',
  reminderAt: string | undefined,
  opts: MindlystClientOptions
): Promise<MemoryItemDoc> {
  return mindlystFetch(
    `/memory-items/${itemId}`,
    { method: 'PATCH', body: JSON.stringify({ action, ...(reminderAt ? { reminderAt } : {}) }) },
    opts
  );
}

export function mindlystMemoryReassign(
  itemId: string,
  newBrainId: string,
  opts: MindlystClientOptions
): Promise<MemoryItemDoc> {
  return mindlystFetch(
    `/memory-items/${itemId}/reassign`,
    { method: 'PUT', body: JSON.stringify({ newBrainId }) },
    opts
  );
}

// ── Brains ─────────────────────────────────────────────────────────────────

export interface BrainDoc {
  id: string;
  userId: string;
  productId: string;
  name: string;
  rolePrompt?: string;
  tone?: string;
  colorFrom?: string;
  colorTo?: string;
  createdAt: string;
  updatedAt: string | null;
}

export function mindlystBrainsList(
  params: { limit?: number; offset?: number },
  opts: MindlystClientOptions
): Promise<{ items: BrainDoc[]; total: number; limit: number; offset: 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 mindlystFetch(`/brains${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

// ── Daily briefs ───────────────────────────────────────────────────────────

export interface DailyBriefDoc {
  id: string;
  userId: string;
  productId: string;
  date: string;
  greeting?: string;
  priorityItems: unknown[];
  brainSummaries: Record<string, string>;
  streakMessage?: string;
  motivationalQuote?: string;
  createdAt: string;
}

export function mindlystBriefCreate(
  body: {
    date: string;
    greeting?: string;
    priorityItems?: unknown[];
    brainSummaries?: Record<string, string>;
    streakMessage?: string;
    motivationalQuote?: string;
  },
  opts: MindlystClientOptions
): Promise<DailyBriefDoc> {
  return mindlystFetch('/daily-briefs', { method: 'POST', body: JSON.stringify(body) }, opts);
}

export function mindlystBriefsGetToday(opts: MindlystClientOptions): Promise<DailyBriefDoc> {
  return mindlystFetch('/daily-briefs/today', { method: 'GET' }, opts);
}

export function mindlystBriefsList(
  params: { limit?: number; offset?: number },
  opts: MindlystClientOptions
): Promise<{ items: DailyBriefDoc[]; 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 mindlystFetch(`/daily-briefs${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

// ── Streaks ────────────────────────────────────────────────────────────────

export interface StreakDoc {
  id: string;
  userId: string;
  productId: string;
  currentStreak: number;
  longestStreak: number;
  lastActiveDate: string;
  streakFreezeAvailable: boolean;
  totalActiveDays: number;
  createdAt: string;
  updatedAt: string;
}

export function mindlystStreaksGet(opts: MindlystClientOptions): Promise<StreakDoc> {
  return mindlystFetch('/streaks', { method: 'GET' }, opts);
}

// ── Reflections ────────────────────────────────────────────────────────────

export interface ReflectionDoc {
  id: string;
  userId: string;
  productId: string;
  weekStartDate: string;
  themes: string[];
  highlights: string[];
  challenges: string[];
  summary?: string;
  createdAt: string;
}

export function mindlystReflectionsList(
  params: { limit?: number; offset?: number },
  opts: MindlystClientOptions
): Promise<{ items: ReflectionDoc[]; 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 mindlystFetch(`/reflections${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}
