import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as api from './client';
import type {
  CreateSubscriptionRequest,
  CreatePaperRunRequest,
  CreateIngestConfigRequest,
  UpdateIngestConfigRequest,
  PaperRun,
  DataRange,
  PaperRunPositionsResponse,
  PaperRunCandlesResponse,
  CandleCoverageEntry,
  BackfillCandlesRequest,
  CreateStrategyRequest,
} from '../types/api';

export function useSubscriptions(activeOnly = true) {
  return useQuery({
    queryKey: ['subscriptions', activeOnly],
    queryFn: () => api.listSubscriptions(activeOnly),
  });
}

export function useCreateSubscription() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (req: CreateSubscriptionRequest) => api.createSubscription(req),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['subscriptions'] });
    },
  });
}

export function useDeactivateSubscription() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (id: number) => api.deactivateSubscription(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['subscriptions'] });
    },
  });
}

export function useIngestConfigs() {
  return useQuery({
    queryKey: ['ingest-configs'],
    queryFn: () => api.listIngestConfigs(),
    refetchInterval: 30_000,
  });
}

export function useCreateIngestConfig() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (req: CreateIngestConfigRequest) => api.createIngestConfig(req),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['ingest-configs'] });
    },
  });
}

export function useUpdateIngestConfig() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ id, ...req }: UpdateIngestConfigRequest & { id: number }) =>
      api.updateIngestConfig(id, req),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['ingest-configs'] });
    },
  });
}

export function useIngestionStats() {
  return useQuery({
    queryKey: ['ingestion-stats'],
    queryFn: () => api.getIngestionStats(),
    refetchInterval: 15_000,
  });
}

export function useExchanges() {
  return useQuery({
    queryKey: ['exchanges'],
    queryFn: () => api.listExchanges(),
    staleTime: 5 * 60 * 1000,
  });
}

export function useExchangeInstruments(exchangeName: string | null) {
  return useQuery({
    queryKey: ['exchange-instruments', exchangeName],
    queryFn: () => api.listExchangeInstruments(exchangeName!),
    enabled: !!exchangeName,
    staleTime: 60 * 60 * 1000,
  });
}

export function useInstrumentDataRange(
  exchange: string | null,
  nameExchange: string | null,
): { data: DataRange | null | undefined; isLoading: boolean } {
  return useQuery({
    queryKey: ['instrument-data-range', exchange, nameExchange],
    queryFn: () => api.getInstrumentDataRange(exchange!, nameExchange!),
    enabled: !!exchange && !!nameExchange,
    staleTime: 60 * 1000,
  });
}

export function usePaperRuns(status?: string, strategyId?: string) {
  return useQuery({
    queryKey: ['paper-runs', status, strategyId],
    queryFn: () => api.listPaperRuns(status, strategyId),
    refetchInterval: 10_000,
  });
}

export function useStrategies() {
  return useQuery({
    queryKey: ['strategies'],
    queryFn: () => api.listStrategies(),
  });
}

export function useStrategy(id: string | undefined) {
  return useQuery({
    queryKey: ['strategies', id],
    queryFn: () => api.getStrategy(id!),
    enabled: !!id,
  });
}

export function useCreateStrategy() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (req: CreateStrategyRequest) => api.createStrategy(req),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['strategies'] });
    },
  });
}

export function usePaperRun(id: string) {
  return useQuery({
    queryKey: ['paper-runs', id],
    queryFn: () => api.getPaperRun(id),
    refetchInterval: (query) => {
      const run = query.state.data as PaperRun | undefined;
      const active = run?.status === 'queued' || run?.status === 'running';
      return active ? 3_000 : false;
    },
  });
}

export function useCancelPaperRun() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => api.cancelPaperRun(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['paper-runs'] });
    },
  });
}

export function usePaperRunPositions(id: string | undefined, samples?: number) {
  return useQuery<PaperRunPositionsResponse>({
    queryKey: ['paper-run-positions', id, samples],
    queryFn: () => api.listPaperRunPositions(id!, samples),
    enabled: !!id,
    staleTime: 60_000,
  });
}

export function usePaperRunCandles(id: string | undefined, candleInterval: string | null) {
  return useQuery<PaperRunCandlesResponse>({
    queryKey: ['paper-run-candles', id],
    queryFn: () => api.listPaperRunCandles(id!),
    enabled: !!id && !!candleInterval,
    staleTime: 60_000,
  });
}

export function useCreatePaperRun() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (req: CreatePaperRunRequest) => api.createPaperRun(req),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['paper-runs'] });
    },
  });
}

export function useCandleCoverage(
  exchange: string | null,
  symbol: string | null,
): { data: CandleCoverageEntry[] | undefined; isLoading: boolean } {
  return useQuery({
    queryKey: ['candle-coverage', exchange, symbol],
    queryFn: () => api.getCandleCoverage(exchange!, symbol!),
    enabled: !!exchange && !!symbol,
    staleTime: 60 * 1000,
  });
}

export function useBackfillCandles() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (req: BackfillCandlesRequest) => api.backfillCandles(req),
    onSuccess: (_data, req) => {
      queryClient.invalidateQueries({
        queryKey: ['candle-coverage', req.exchange, req.symbol],
      });
    },
  });
}
