import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type {
  DriverLocation,
  GpsDevice,
  DriverStats,
  GpsStatus,
  GpsSettings,
  EnrollmentResponse,
  MyGpsStatus,
} from '@/types/gps';
import toast from 'react-hot-toast';

// ============================================
// Admin GPS Hooks
// ============================================

/**
 * Get GPS system status
 */
export function useGpsStatus() {
  return useQuery<GpsStatus>({
    queryKey: ['gps', 'status'],
    queryFn: async () => {
      const { data } = await api.get('/gps/status');
      return data;
    },
    refetchInterval: 30000, // Refresh every 30 seconds
  });
}

/**
 * Get GPS settings
 */
export function useGpsSettings() {
  return useQuery<GpsSettings>({
    queryKey: ['gps', 'settings'],
    queryFn: async () => {
      const { data } = await api.get('/gps/settings');
      return data;
    },
  });
}

/**
 * Update GPS settings
 */
export function useUpdateGpsSettings() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (settings: Partial<GpsSettings>) => {
      const { data } = await api.patch('/gps/settings', settings);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['gps', 'settings'] });
      queryClient.invalidateQueries({ queryKey: ['gps', 'status'] });
      toast.success('GPS settings updated');
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to update GPS settings');
    },
  });
}

/**
 * Get all enrolled GPS devices
 */
export function useGpsDevices() {
  return useQuery<GpsDevice[]>({
    queryKey: ['gps', 'devices'],
    queryFn: async () => {
      const { data } = await api.get('/gps/devices');
      return data;
    },
  });
}

/**
 * Get all active driver locations (for map)
 */
export function useDriverLocations() {
  return useQuery<DriverLocation[]>({
    queryKey: ['gps', 'locations'],
    queryFn: async () => {
      const { data } = await api.get('/gps/locations');
      return data;
    },
    refetchInterval: 30000, // Refresh every 30 seconds
  });
}

/**
 * Get a specific driver's location
 */
export function useDriverLocation(driverId: string) {
  return useQuery<DriverLocation>({
    queryKey: ['gps', 'locations', driverId],
    queryFn: async () => {
      const { data } = await api.get(`/gps/locations/${driverId}`);
      return data;
    },
    enabled: !!driverId,
    refetchInterval: 30000,
  });
}

/**
 * Get driver stats
 */
export function useDriverStats(driverId: string, from?: string, to?: string) {
  return useQuery<DriverStats>({
    queryKey: ['gps', 'stats', driverId, from, to],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (from) params.append('from', from);
      if (to) params.append('to', to);
      const { data } = await api.get(`/gps/stats/${driverId}?${params.toString()}`);
      return data;
    },
    enabled: !!driverId,
  });
}

/**
 * Enroll a driver for GPS tracking
 */
export function useEnrollDriver() {
  const queryClient = useQueryClient();

  return useMutation<EnrollmentResponse, Error, { driverId: string; sendSignalMessage?: boolean }>({
    mutationFn: async ({ driverId, sendSignalMessage = true }) => {
      const { data } = await api.post(`/gps/enroll/${driverId}`, { sendSignalMessage });
      return data;
    },
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['gps', 'devices'] });
      queryClient.invalidateQueries({ queryKey: ['gps', 'status'] });
      queryClient.invalidateQueries({ queryKey: ['drivers'] });
      if (data.signalMessageSent) {
        toast.success('Driver enrolled! Setup instructions sent via Signal.');
      } else {
        toast.success('Driver enrolled! Share the setup instructions with them.');
      }
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to enroll driver');
    },
  });
}

/**
 * Unenroll a driver from GPS tracking
 */
export function useUnenrollDriver() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (driverId: string) => {
      const { data } = await api.delete(`/gps/devices/${driverId}`);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['gps', 'devices'] });
      queryClient.invalidateQueries({ queryKey: ['gps', 'status'] });
      queryClient.invalidateQueries({ queryKey: ['gps', 'locations'] });
      queryClient.invalidateQueries({ queryKey: ['drivers'] });
      toast.success('Driver unenrolled from GPS tracking');
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to unenroll driver');
    },
  });
}

// ============================================
// Driver Self-Service Hooks
// ============================================

/**
 * Get my GPS enrollment status (for drivers)
 */
export function useMyGpsStatus() {
  return useQuery<MyGpsStatus>({
    queryKey: ['gps', 'me'],
    queryFn: async () => {
      const { data } = await api.get('/gps/me');
      return data;
    },
  });
}

/**
 * Get my GPS stats (for drivers)
 */
export function useMyGpsStats(from?: string, to?: string) {
  return useQuery<DriverStats>({
    queryKey: ['gps', 'me', 'stats', from, to],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (from) params.append('from', from);
      if (to) params.append('to', to);
      const { data } = await api.get(`/gps/me/stats?${params.toString()}`);
      return data;
    },
  });
}

/**
 * Get my current location (for drivers)
 */
export function useMyLocation() {
  return useQuery<DriverLocation>({
    queryKey: ['gps', 'me', 'location'],
    queryFn: async () => {
      const { data } = await api.get('/gps/me/location');
      return data;
    },
    refetchInterval: 30000,
  });
}

/**
 * Confirm/revoke GPS tracking consent (for drivers)
 */
export function useUpdateGpsConsent() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (consentGiven: boolean) => {
      const { data } = await api.post('/gps/me/consent', { consentGiven });
      return data;
    },
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['gps', 'me'] });
      toast.success(data.message);
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to update consent');
    },
  });
}

// ============================================
// Traccar Admin Hooks
// ============================================

/**
 * Check Traccar setup status
 */
export function useTraccarSetupStatus() {
  return useQuery<{ needsSetup: boolean; isAvailable: boolean }>({
    queryKey: ['gps', 'traccar', 'status'],
    queryFn: async () => {
      const { data } = await api.get('/gps/traccar/status');
      return data;
    },
  });
}

/**
 * Perform initial Traccar setup
 */
export function useTraccarSetup() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async () => {
      const { data } = await api.post('/gps/traccar/setup');
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['gps', 'traccar', 'status'] });
      queryClient.invalidateQueries({ queryKey: ['gps', 'status'] });
      toast.success('Traccar setup complete!');
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to setup Traccar');
    },
  });
}

/**
 * Sync VIP admins to Traccar
 */
export function useSyncAdminsToTraccar() {
  return useMutation({
    mutationFn: async () => {
      const { data } = await api.post('/gps/traccar/sync-admins');
      return data;
    },
    onSuccess: (data: { synced: number; failed: number }) => {
      toast.success(`Synced ${data.synced} admins to Traccar`);
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to sync admins');
    },
  });
}

/**
 * Get Traccar admin URL for current user
 */
export function useTraccarAdminUrl() {
  return useQuery<{ url: string; directAccess: boolean }>({
    queryKey: ['gps', 'traccar', 'admin-url'],
    queryFn: async () => {
      const { data } = await api.get('/gps/traccar/admin-url');
      return data;
    },
    enabled: false, // Only fetch when explicitly called
  });
}

/**
 * Open Traccar admin (fetches URL and opens in new tab)
 */
export function useOpenTraccarAdmin() {
  return useMutation({
    mutationFn: async () => {
      const { data } = await api.get('/gps/traccar/admin-url');
      return data;
    },
    onSuccess: (data: { url: string; directAccess: boolean }) => {
      // Open Traccar in new tab
      window.open(data.url, '_blank');
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || 'Failed to open Traccar admin');
    },
  });
}
