import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import * as adminApi from '../api/admin';
import { useToast } from '../components/ui/Toast';
import type { TickerUniverse } from '../lib/types';

// ── Users ──

export function useUsers() {
  return useQuery({
    queryKey: ['admin', 'users'],
    queryFn: () => adminApi.listUsers(),
  });
}

export function useCreateUser() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (data: {
      username: string;
      password: string;
      role: string;
      has_access: boolean;
    }) => adminApi.createUser(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to create user');
    },
  });
}

export function useUpdateAccess() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: ({ userId, hasAccess }: { userId: number; hasAccess: boolean }) =>
      adminApi.updateAccess(userId, hasAccess),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update access');
    },
  });
}

export function useResetPassword() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: ({ userId, password }: { userId: number; password: string }) =>
      adminApi.resetPassword(userId, password),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
      addToast('success', 'Password reset successfully');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to reset password');
    },
  });
}

// ── Settings ──

export function useSettings() {
  return useQuery({
    queryKey: ['admin', 'settings'],
    queryFn: () => adminApi.listSettings(),
  });
}

export function useUpdateSetting() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: ({ key, value }: { key: string; value: string }) =>
      adminApi.updateSetting(key, value),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'settings'] });
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update setting');
    },
  });
}

export function useRecommendationSettings() {
  return useQuery({
    queryKey: ['admin', 'recommendation-settings'],
    queryFn: () => adminApi.getRecommendationSettings(),
  });
}

export function useUpdateRecommendationSettings() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (payload: Record<string, number>) =>
      adminApi.updateRecommendationSettings(payload),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'recommendation-settings'] });
      addToast('success', 'Recommendation settings updated');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update recommendation settings');
    },
  });
}

export function useActivationSettings() {
  return useQuery({
    queryKey: ['admin', 'activation-settings'],
    queryFn: () => adminApi.getActivationSettings(),
  });
}

export function useUpdateActivationSettings() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (payload: Partial<import('../lib/types').ActivationConfig>) =>
      adminApi.updateActivationSettings(payload),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'activation-settings'] });
      qc.invalidateQueries({ queryKey: ['activation'] });
      qc.invalidateQueries({ queryKey: ['performance'] });
      addToast('success', 'Activation gate updated');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update activation thresholds');
    },
  });
}

export function useScheduleSettings() {
  return useQuery({
    queryKey: ['admin', 'schedule-settings'],
    queryFn: () => adminApi.getScheduleSettings(),
  });
}

export function useUpdateScheduleSettings() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (payload: Partial<import('../lib/types').ScheduleConfig>) =>
      adminApi.updateScheduleSettings(payload),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'schedule-settings'] });
      qc.invalidateQueries({ queryKey: ['admin', 'jobs'] });
      addToast('success', 'Schedule updated');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update schedule');
    },
  });
}

export function useSentimentSettings() {
  return useQuery({
    queryKey: ['admin', 'sentiment-settings'],
    queryFn: () => adminApi.getSentimentSettings(),
  });
}

export function useUpdateSentimentSettings() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (payload: { provider?: string; model?: string; api_key?: string }) =>
      adminApi.updateSentimentSettings(payload),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'sentiment-settings'] });
      addToast('success', 'Sentiment provider updated');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update sentiment provider');
    },
  });
}

export function useTestSentimentProvider() {
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (ticker: string) => adminApi.testSentimentSettings(ticker),
    onError: (error: Error) => {
      addToast('error', error.message || 'Sentiment test failed');
    },
  });
}

export function useAlertSettings() {
  return useQuery({
    queryKey: ['admin', 'alert-settings'],
    queryFn: () => adminApi.getAlertSettings(),
  });
}

export function useUpdateAlertSettings() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (payload: Parameters<typeof adminApi.updateAlertSettings>[0]) =>
      adminApi.updateAlertSettings(payload),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'alert-settings'] });
      addToast('success', 'Alert settings updated');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update alert settings');
    },
  });
}

export function useTestAlert() {
  const { addToast } = useToast();

  return useMutation({
    mutationFn: () => adminApi.testAlertSettings(),
    onSuccess: (result) => {
      if (result.ok) addToast('success', 'Test alert sent — check Telegram.');
      else addToast('error', result.error || 'Test alert failed');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Test alert failed');
    },
  });
}

export function useTickerUniverseSetting() {
  return useQuery({
    queryKey: ['admin', 'ticker-universe'],
    queryFn: () => adminApi.getTickerUniverseSetting(),
  });
}

export function useUpdateTickerUniverseSetting() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (universe: TickerUniverse) => adminApi.updateTickerUniverseSetting(universe),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'ticker-universe'] });
      addToast('success', 'Default ticker universe updated');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to update default ticker universe');
    },
  });
}

export function useBootstrapTickers() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: ({ universe, pruneMissing }: { universe: TickerUniverse; pruneMissing: boolean }) =>
      adminApi.bootstrapTickers(universe, pruneMissing),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['tickers'] });
      qc.invalidateQueries({ queryKey: ['admin', 'ticker-universe'] });
      addToast(
        'success',
        `Bootstrap done: +${result.added}, existing ${result.already_tracked}, deleted ${result.deleted}`,
      );
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to bootstrap tickers');
    },
  });
}

export function useBackfillTickerNames() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: () => adminApi.backfillTickerNames(),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['tickers'] });
      addToast('success', `Company names: +${result.updated} filled (${result.unmatched} unmatched)`);
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to backfill company names');
    },
  });
}

// ── Jobs ──

export function useJobs() {
  return useQuery({
    queryKey: ['admin', 'jobs'],
    queryFn: () => adminApi.listJobs(),
    refetchInterval: (query) => {
      const jobs = (query.state.data ?? []) as adminApi.JobStatus[];
      const hasRunning = jobs.some((job) => job.running);
      return hasRunning ? 2_000 : 15_000;
    },
  });
}

export function usePipelineReadiness() {
  return useQuery({
    queryKey: ['admin', 'pipeline-readiness'],
    queryFn: () => adminApi.getPipelineReadiness(),
    refetchInterval: 20_000,
  });
}

export function useToggleJob() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: ({ jobName, enabled }: { jobName: string; enabled: boolean }) =>
      adminApi.toggleJob(jobName, enabled),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'jobs'] });
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to toggle job');
    },
  });
}

export function useTriggerJob() {
  const qc = useQueryClient();
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (jobName: string) => adminApi.triggerJob(jobName),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['admin', 'jobs'] });
      if (result.status === 'triggered') {
        addToast('success', result.message || 'Job triggered successfully');
        return;
      }
      addToast('info', result.message || 'Job could not be triggered');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to trigger job');
    },
  });
}

// ── Data Cleanup ──

export function useCleanupData() {
  const { addToast } = useToast();

  return useMutation({
    mutationFn: (olderThanDays: number) => adminApi.cleanupData(olderThanDays),
    onSuccess: (data) => {
      addToast('success', (data as { message: string }).message || 'Cleanup completed');
    },
    onError: (error: Error) => {
      addToast('error', error.message || 'Failed to cleanup data');
    },
  });
}
