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

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

export interface LysnraiClientOptions {
  token?: string;
  requestId?: string;
}

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

async function lysnraiFetch<T>(
  path: string,
  init: RequestInit,
  opts: LysnraiClientOptions
): Promise<T> {
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(opts.token ? { Authorization: `Bearer ${opts.token}` } : {}),
    ...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
  };
  const res = await fetch(`${config.LYSNRAI_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(`lysnrai-backend ${init.method ?? 'GET'} ${path} → ${res.status}: ${body}`);
  }
  return res.json() as Promise<T>;
}

// ── Transcripts ────────────────────────────────────────────────────────────

export interface TranscriptDoc {
  id: string;
  userId: string;
  productId: string;
  rawText?: string;
  cleanedText?: string;
  wordCount?: number;
  duration?: number;
  tokensUsed?: number;
  context?: string;
  source?: string;
  language?: string;
  extractions?: unknown[];
  extractionMetadata?: Record<string, unknown>;
  extractedAt?: string;
  createdAt: string;
}

export function lysnraiTranscriptsList(
  params: { limit?: number; offset?: number },
  opts: LysnraiClientOptions
): Promise<{ transcripts: TranscriptDoc[]; 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 lysnraiFetch(`/transcripts${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

export function lysnraiTranscriptGet(
  id: string,
  opts: LysnraiClientOptions
): Promise<TranscriptDoc> {
  return lysnraiFetch(`/transcripts/${id}`, { method: 'GET' }, opts);
}

export function lysnraiTranscriptRunExtraction(
  transcriptId: string,
  opts: LysnraiClientOptions
): Promise<TranscriptDoc> {
  return lysnraiFetch(`/transcripts/${transcriptId}/extract`, { method: 'POST' }, opts);
}

// ── STT status ─────────────────────────────────────────────────────────────

export interface SttStatusResult {
  productId: string;
  primary: 'azure' | 'whisper' | 'none';
  azureConfigured: boolean;
  whisperConfigured: boolean;
  azureRegion: string | null;
  generatedAt: string;
}

export function lysnraiSttGetBackendStatus(opts: LysnraiClientOptions): Promise<SttStatusResult> {
  return lysnraiFetch('/transcripts/stt-status', { method: 'GET' }, opts);
}

// ── Sessions ───────────────────────────────────────────────────────────────

export interface SessionDoc {
  id: string;
  userId: string;
  productId: string;
  title: string;
  status: 'active' | 'composed' | 'archived';
  entries: unknown[];
  composedText: string | null;
  composedAt: string | null;
  compositionRating: number | null;
  createdAt: string;
  updatedAt: string;
}

export function lysnraiSessionGet(
  sessionId: string,
  opts: LysnraiClientOptions
): Promise<SessionDoc> {
  return lysnraiFetch(`/sessions/${sessionId}`, { method: 'GET' }, opts);
}

export function lysnraiSessionsList(
  params: { limit?: number; offset?: number; status?: string },
  opts: LysnraiClientOptions
): Promise<{ sessions: SessionDoc[]; 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);
  const q = qs.toString();
  return lysnraiFetch(`/sessions${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

// ── Organisations ──────────────────────────────────────────────────────────

export interface OrgDoc {
  id: string;
  name: string;
  ownerId: string;
  productId: string;
  createdAt: string;
}

export function lysnraiOrgGet(orgId: string, opts: LysnraiClientOptions): Promise<OrgDoc> {
  return lysnraiFetch(`/orgs/${orgId}`, { method: 'GET' }, opts);
}

export function lysnraiOrgsList(
  params: { limit?: number; offset?: number },
  opts: LysnraiClientOptions
): Promise<{ organizations: OrgDoc[] }> {
  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 lysnraiFetch(`/orgs${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

// ── API tokens ─────────────────────────────────────────────────────────────

export interface ApiTokenDoc {
  id: string;
  userId: string;
  productId: string;
  name: string;
  lastUsedAt: string | null;
  createdAt: string;
}

export function lysnraiApiTokensList(
  params: { limit?: number; offset?: number },
  opts: LysnraiClientOptions
): Promise<{ tokens: ApiTokenDoc[] }> {
  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 lysnraiFetch(`/api-tokens${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}

export function lysnraiApiTokenCreate(
  input: { name: string },
  opts: LysnraiClientOptions
): Promise<ApiTokenDoc & { rawToken: string }> {
  return lysnraiFetch('/api-tokens', { method: 'POST', body: JSON.stringify(input) }, opts);
}

export function lysnraiApiTokenRevoke(
  tokenId: string,
  opts: LysnraiClientOptions
): Promise<{ success: boolean }> {
  return lysnraiFetch(`/api-tokens/${tokenId}`, { method: 'DELETE' }, opts);
}

export function lysnraiSessionsStats(opts: LysnraiClientOptions): Promise<Record<string, unknown>> {
  return lysnraiFetch('/sessions/stats', { method: 'GET' }, opts);
}

export function lysnraiTranscriptsExportBatch(
  params: { format?: 'json' | 'txt'; limit?: number },
  opts: LysnraiClientOptions
): Promise<{ exportUrl: string; count: number; format: string; generatedAt: string }> {
  const qs = new URLSearchParams();
  if (params.format) qs.set('format', params.format);
  if (params.limit !== undefined) qs.set('limit', String(params.limit));
  const q = qs.toString();
  return lysnraiFetch(`/transcripts/export${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}
