/**
 * @ai-summary React Query hooks for Backup & Restore admin feature
 * @ai-context Provides hooks for managing backups, schedules, and settings
 */

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { adminApi } from '../api/admin.api';
import {
  BackupSettings,
  CreateBackupRequest,
  CreateScheduleRequest,
  UpdateScheduleRequest,
  ExecuteRestoreRequest,
} from '../types/admin.types';
import toast from 'react-hot-toast';

// Query keys
export const backupKeys = {
  all: ['admin', 'backups'] as const,
  lists: () => [...backupKeys.all, 'list'] as const,
  list: (params: { page?: number; pageSize?: number }) =>
    [...backupKeys.lists(), params] as const,
  details: () => [...backupKeys.all, 'detail'] as const,
  detail: (id: string) => [...backupKeys.details(), id] as const,
  schedules: () => [...backupKeys.all, 'schedules'] as const,
  settings: () => [...backupKeys.all, 'settings'] as const,
};

// List backups with pagination
export const useBackups = (params: { page?: number; pageSize?: number } = {}) => {
  return useQuery({
    queryKey: backupKeys.list(params),
    queryFn: () => adminApi.backups.list(params),
  });
};

// Get backup details
export const useBackupDetails = (id: string) => {
  return useQuery({
    queryKey: backupKeys.detail(id),
    queryFn: () => adminApi.backups.get(id),
    enabled: !!id,
  });
};

// List backup schedules
export const useBackupSchedules = () => {
  return useQuery({
    queryKey: backupKeys.schedules(),
    queryFn: () => adminApi.backups.schedules.list(),
  });
};

// Get backup settings
export const useBackupSettings = () => {
  return useQuery({
    queryKey: backupKeys.settings(),
    queryFn: () => adminApi.backups.settings.get(),
  });
};

// Create manual backup
export const useCreateBackup = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateBackupRequest) => adminApi.backups.create(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.lists() });
      toast.success('Backup created successfully');
    },
    onError: () => {
      toast.error('Failed to create backup');
    },
  });
};

// Delete backup
export const useDeleteBackup = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => adminApi.backups.delete(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.lists() });
      toast.success('Backup deleted successfully');
    },
    onError: () => {
      toast.error('Failed to delete backup');
    },
  });
};

// Download backup
export const useDownloadBackup = () => {
  return useMutation({
    mutationFn: async ({ id, filename }: { id: string; filename: string }) => {
      const blob = await adminApi.backups.download(id);
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    },
    onSuccess: () => {
      toast.success('Backup download started');
    },
    onError: () => {
      toast.error('Failed to download backup');
    },
  });
};

// Upload backup
export const useUploadBackup = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (file: File) => adminApi.backups.upload(file),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.lists() });
      toast.success('Backup uploaded successfully');
    },
    onError: () => {
      toast.error('Failed to upload backup');
    },
  });
};

// Preview restore
export const useRestorePreview = () => {
  return useMutation({
    mutationFn: (id: string) => adminApi.backups.previewRestore(id),
    onError: () => {
      toast.error('Failed to generate restore preview');
    },
  });
};

// Execute restore
export const useExecuteRestore = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, options }: { id: string; options?: ExecuteRestoreRequest }) =>
      adminApi.backups.restore(id, options),
    retry: false,
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: backupKeys.all });
      toast.success(data.message || 'Restore completed successfully');
    },
    onError: () => {
      toast.error('Failed to restore backup');
    },
  });
};

// Create schedule
export const useCreateSchedule = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateScheduleRequest) => adminApi.backups.schedules.create(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.schedules() });
      toast.success('Schedule created successfully');
    },
    onError: () => {
      toast.error('Failed to create schedule');
    },
  });
};

// Update schedule
export const useUpdateSchedule = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateScheduleRequest }) =>
      adminApi.backups.schedules.update(id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.schedules() });
      toast.success('Schedule updated successfully');
    },
    onError: () => {
      toast.error('Failed to update schedule');
    },
  });
};

// Delete schedule
export const useDeleteSchedule = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => adminApi.backups.schedules.delete(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.schedules() });
      toast.success('Schedule deleted successfully');
    },
    onError: () => {
      toast.error('Failed to delete schedule');
    },
  });
};

// Toggle schedule enabled/disabled
export const useToggleSchedule = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => adminApi.backups.schedules.toggle(id),
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: backupKeys.schedules() });
      toast.success(
        data.isEnabled ? 'Schedule enabled successfully' : 'Schedule disabled successfully'
      );
    },
    onError: () => {
      toast.error('Failed to toggle schedule');
    },
  });
};

// Update settings
export const useUpdateSettings = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: Partial<BackupSettings>) => adminApi.backups.settings.update(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: backupKeys.settings() });
      toast.success('Settings updated successfully');
    },
    onError: () => {
      toast.error('Failed to update settings');
    },
  });
};
