import type {
  Subscription,
  SubscriptionSimple,
  CreateSubscriptionRequest,
  CreatePaperRunRequest,
  IngestConfig,
  CreateIngestConfigRequest,
  UpdateIngestConfigRequest,
  InstrumentStats,
  InstrumentPair,
  Exchange,
  PaperRun,
  PaperRunPositionsResponse,
  PaperRunCandlesResponse,
  DataRange,
  CandleCoverageEntry,
  BackfillCandlesRequest,
  BackfillCandlesResponse,
  Strategy,
  CreateStrategyRequest,
} from '../types/api';

async function json<T>(response: Response): Promise<T> {
  if (!response.ok) {
    const body = await response.text();
    throw new Error(`${response.status}: ${body}`);
  }
  return response.json();
}

export async function listSubscriptions(activeOnly = true): Promise<Subscription[]> {
  const res = await fetch(`/api/v1/market-subscriptions?active_only=${activeOnly}`);
  return json(res);
}

export async function createSubscription(
  req: CreateSubscriptionRequest,
): Promise<SubscriptionSimple[]> {
  const res = await fetch('/api/v1/market-subscriptions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  return json(res);
}

export async function deactivateSubscription(id: number): Promise<SubscriptionSimple> {
  const res = await fetch(`/api/v1/market-subscriptions/${id}`, {
    method: 'DELETE',
  });
  return json(res);
}

export async function listIngestConfigs(): Promise<IngestConfig[]> {
  const res = await fetch('/api/v1/ingest-configs');
  return json(res);
}

export async function createIngestConfig(req: CreateIngestConfigRequest): Promise<IngestConfig> {
  const res = await fetch('/api/v1/ingest-configs', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  return json(res);
}

export async function updateIngestConfig(
  id: number,
  req: UpdateIngestConfigRequest,
): Promise<IngestConfig> {
  const res = await fetch(`/api/v1/ingest-configs/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  return json(res);
}

export async function getIngestionStats(): Promise<InstrumentStats[]> {
  const res = await fetch('/api/v1/ingestion-stats');
  return json(res);
}

export async function listExchanges(): Promise<Exchange[]> {
  const res = await fetch('/api/v1/exchanges');
  return json(res);
}

export async function listExchangeInstruments(name: string): Promise<InstrumentPair[]> {
  const res = await fetch(`/api/v1/exchanges/${name}/instruments`);
  return json(res);
}

export async function getInstrumentDataRange(
  exchange: string,
  name: string,
): Promise<DataRange | null> {
  const res = await fetch(`/api/v1/instruments/${exchange}/${name}/data-range`);
  if (!res.ok) return null;
  const body = await res.json();
  return body ?? null;
}

export async function listPaperRuns(status?: string, strategyId?: string): Promise<PaperRun[]> {
  const params = new URLSearchParams();
  if (status) params.set('status', status);
  if (strategyId) params.set('strategy_id', strategyId);
  const qs = params.size > 0 ? `?${params}` : '';
  const res = await fetch(`/api/v1/paper-runs${qs}`);
  return json(res);
}

export async function listStrategies(): Promise<Strategy[]> {
  const res = await fetch('/api/v1/strategies');
  return json(res);
}

export async function getStrategy(id: string): Promise<Strategy> {
  const res = await fetch(`/api/v1/strategies/${id}`);
  return json(res);
}

export async function createStrategy(req: CreateStrategyRequest): Promise<Strategy> {
  const res = await fetch('/api/v1/strategies', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  return json(res);
}

export async function getPaperRun(id: string): Promise<PaperRun> {
  const res = await fetch(`/api/v1/paper-runs/${id}`);
  return json(res);
}

export async function cancelPaperRun(id: string): Promise<PaperRun> {
  const res = await fetch(`/api/v1/paper-runs/${id}/cancel`, { method: 'POST' });
  return json(res);
}

export async function listPaperRunPositions(
  id: string,
  samples?: number,
): Promise<PaperRunPositionsResponse> {
  const params = samples != null ? `?samples=${samples}` : '';
  const res = await fetch(`/api/v1/paper-runs/${id}/positions${params}`);
  return json(res);
}

export async function createPaperRun(req: CreatePaperRunRequest): Promise<PaperRun> {
  const res = await fetch('/api/v1/paper-runs', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  return json(res);
}

export async function getCandleCoverage(
  exchange: string,
  symbol: string,
): Promise<CandleCoverageEntry[]> {
  const res = await fetch(`/api/v1/market-candles/coverage/${exchange}/${symbol}`);
  return json(res);
}

export async function backfillCandles(
  req: BackfillCandlesRequest,
): Promise<BackfillCandlesResponse> {
  const res = await fetch('/api/v1/market-candles/backfill', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  return json(res);
}

export async function listPaperRunCandles(id: string): Promise<PaperRunCandlesResponse> {
  const res = await fetch(`/api/v1/paper-runs/${id}/candles`);
  return json(res);
}
