/**
 * Food Safety React Query hooks
 */
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { foodSafetyService } from '../services/foodSafety';
import {
  FoodSafetyComplianceCreate,
  FoodSafetyComplianceUpdate,
  FoodSafetyComplianceResponse,
  TemperatureLogCreate,
  BulkTemperatureLogCreate,
  TemperatureLogResponse,
  FoodSafetyAlertCreate,
  FoodSafetyAlertUpdate,
  FoodSafetyAlertResponse,
  FoodSafetyFilter,
  TemperatureMonitoringFilter,
  FoodSafetyMetrics,
  TemperatureAnalytics,
  FoodSafetyDashboard,
} from '../types/foodSafety';
import { PaginatedResponse } from '../types/inventory';
import { ApiError } from '../client';

// Query Keys
export const foodSafetyKeys = {
  all: ['food-safety'] as const,
  compliance: {
    all: () => [...foodSafetyKeys.all, 'compliance'] as const,
    lists: () => [...foodSafetyKeys.compliance.all(), 'list'] as const,
    list: (tenantId: string, filter?: FoodSafetyFilter) => 
      [...foodSafetyKeys.compliance.lists(), tenantId, filter] as const,
    details: () => [...foodSafetyKeys.compliance.all(), 'detail'] as const,
    detail: (tenantId: string, recordId: string) => 
      [...foodSafetyKeys.compliance.details(), tenantId, recordId] as const,
  },
  temperature: {
    all: () => [...foodSafetyKeys.all, 'temperature'] as const,
    lists: () => [...foodSafetyKeys.temperature.all(), 'list'] as const,
    list: (tenantId: string, filter?: TemperatureMonitoringFilter) => 
      [...foodSafetyKeys.temperature.lists(), tenantId, filter] as const,
    analytics: (tenantId: string, location: string, startDate?: string, endDate?: string) => 
      [...foodSafetyKeys.temperature.all(), 'analytics', tenantId, location, { startDate, endDate }] as const,
    violations: (tenantId: string, limit?: number) => 
      [...foodSafetyKeys.temperature.all(), 'violations', tenantId, limit] as const,
  },
  alerts: {
    all: () => [...foodSafetyKeys.all, 'alerts'] as const,
    lists: () => [...foodSafetyKeys.alerts.all(), 'list'] as const,
    list: (tenantId: string, status?: string, severity?: string, limit?: number, offset?: number) => 
      [...foodSafetyKeys.alerts.lists(), tenantId, { status, severity, limit, offset }] as const,
    details: () => [...foodSafetyKeys.alerts.all(), 'detail'] as const,
    detail: (tenantId: string, alertId: string) => 
      [...foodSafetyKeys.alerts.details(), tenantId, alertId] as const,
  },
  dashboard: (tenantId: string) => 
    [...foodSafetyKeys.all, 'dashboard', tenantId] as const,
  metrics: (tenantId: string, startDate?: string, endDate?: string) => 
    [...foodSafetyKeys.all, 'metrics', tenantId, { startDate, endDate }] as const,
  complianceRate: (tenantId: string, startDate?: string, endDate?: string) => 
    [...foodSafetyKeys.all, 'compliance-rate', tenantId, { startDate, endDate }] as const,
} as const;

// Compliance Queries
export const useComplianceRecords = (
  tenantId: string,
  filter?: FoodSafetyFilter,
  options?: Omit<UseQueryOptions<PaginatedResponse<FoodSafetyComplianceResponse>, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PaginatedResponse<FoodSafetyComplianceResponse>, ApiError>({
    queryKey: foodSafetyKeys.compliance.list(tenantId, filter),
    queryFn: () => foodSafetyService.getComplianceRecords(tenantId, filter),
    enabled: !!tenantId,
    staleTime: 1 * 60 * 1000, // 1 minute
    ...options,
  });
};

export const useComplianceRecord = (
  tenantId: string,
  recordId: string,
  options?: Omit<UseQueryOptions<FoodSafetyComplianceResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<FoodSafetyComplianceResponse, ApiError>({
    queryKey: foodSafetyKeys.compliance.detail(tenantId, recordId),
    queryFn: () => foodSafetyService.getComplianceRecord(tenantId, recordId),
    enabled: !!tenantId && !!recordId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

// Temperature Monitoring Queries
export const useTemperatureLogs = (
  tenantId: string,
  filter?: TemperatureMonitoringFilter,
  options?: Omit<UseQueryOptions<PaginatedResponse<TemperatureLogResponse>, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PaginatedResponse<TemperatureLogResponse>, ApiError>({
    queryKey: foodSafetyKeys.temperature.list(tenantId, filter),
    queryFn: () => foodSafetyService.getTemperatureLogs(tenantId, filter),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

export const useTemperatureAnalytics = (
  tenantId: string,
  location: string,
  startDate?: string,
  endDate?: string,
  options?: Omit<UseQueryOptions<TemperatureAnalytics, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<TemperatureAnalytics, ApiError>({
    queryKey: foodSafetyKeys.temperature.analytics(tenantId, location, startDate, endDate),
    queryFn: () => foodSafetyService.getTemperatureAnalytics(tenantId, location, startDate, endDate),
    enabled: !!tenantId && !!location,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

export const useTemperatureViolations = (
  tenantId: string,
  limit: number = 20,
  options?: Omit<UseQueryOptions<TemperatureLogResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<TemperatureLogResponse[], ApiError>({
    queryKey: foodSafetyKeys.temperature.violations(tenantId, limit),
    queryFn: () => foodSafetyService.getTemperatureViolations(tenantId, limit),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

// Alert Queries
export const useFoodSafetyAlerts = (
  tenantId: string,
  status?: 'open' | 'in_progress' | 'resolved' | 'dismissed',
  severity?: 'critical' | 'warning' | 'info',
  limit: number = 50,
  offset: number = 0,
  options?: Omit<UseQueryOptions<PaginatedResponse<FoodSafetyAlertResponse>, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PaginatedResponse<FoodSafetyAlertResponse>, ApiError>({
    queryKey: foodSafetyKeys.alerts.list(tenantId, status, severity, limit, offset),
    queryFn: () => foodSafetyService.getFoodSafetyAlerts(tenantId, status, severity, limit, offset),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

export const useFoodSafetyAlert = (
  tenantId: string,
  alertId: string,
  options?: Omit<UseQueryOptions<FoodSafetyAlertResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<FoodSafetyAlertResponse, ApiError>({
    queryKey: foodSafetyKeys.alerts.detail(tenantId, alertId),
    queryFn: () => foodSafetyService.getFoodSafetyAlert(tenantId, alertId),
    enabled: !!tenantId && !!alertId,
    staleTime: 1 * 60 * 1000, // 1 minute
    ...options,
  });
};

// Dashboard and Metrics Queries
export const useFoodSafetyDashboard = (
  tenantId: string,
  options?: Omit<UseQueryOptions<FoodSafetyDashboard, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<FoodSafetyDashboard, ApiError>({
    queryKey: foodSafetyKeys.dashboard(tenantId),
    queryFn: () => foodSafetyService.getFoodSafetyDashboard(tenantId),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

export const useFoodSafetyMetrics = (
  tenantId: string,
  startDate?: string,
  endDate?: string,
  options?: Omit<UseQueryOptions<FoodSafetyMetrics, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<FoodSafetyMetrics, ApiError>({
    queryKey: foodSafetyKeys.metrics(tenantId, startDate, endDate),
    queryFn: () => foodSafetyService.getFoodSafetyMetrics(tenantId, startDate, endDate),
    enabled: !!tenantId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

export const useComplianceRate = (
  tenantId: string,
  startDate?: string,
  endDate?: string,
  options?: Omit<UseQueryOptions<{
    overall_rate: number;
    by_type: Record<string, number>;
    trend: Array<{ date: string; rate: number }>;
  }, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<{
    overall_rate: number;
    by_type: Record<string, number>;
    trend: Array<{ date: string; rate: number }>;
  }, ApiError>({
    queryKey: foodSafetyKeys.complianceRate(tenantId, startDate, endDate),
    queryFn: () => foodSafetyService.getComplianceRate(tenantId, startDate, endDate),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

// Compliance Mutations
export const useCreateComplianceRecord = (
  options?: UseMutationOptions<
    FoodSafetyComplianceResponse, 
    ApiError, 
    { tenantId: string; complianceData: FoodSafetyComplianceCreate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    FoodSafetyComplianceResponse, 
    ApiError, 
    { tenantId: string; complianceData: FoodSafetyComplianceCreate }
  >({
    mutationFn: ({ tenantId, complianceData }) => 
      foodSafetyService.createComplianceRecord(tenantId, complianceData),
    onSuccess: (data, { tenantId }) => {
      // Add to cache
      queryClient.setQueryData(foodSafetyKeys.compliance.detail(tenantId, data.id), data);
      // Invalidate lists
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.compliance.lists() });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.dashboard(tenantId) });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.metrics(tenantId) });
    },
    ...options,
  });
};

export const useUpdateComplianceRecord = (
  options?: UseMutationOptions<
    FoodSafetyComplianceResponse, 
    ApiError, 
    { tenantId: string; recordId: string; updateData: FoodSafetyComplianceUpdate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    FoodSafetyComplianceResponse, 
    ApiError, 
    { tenantId: string; recordId: string; updateData: FoodSafetyComplianceUpdate }
  >({
    mutationFn: ({ tenantId, recordId, updateData }) => 
      foodSafetyService.updateComplianceRecord(tenantId, recordId, updateData),
    onSuccess: (data, { tenantId, recordId }) => {
      // Update cache
      queryClient.setQueryData(foodSafetyKeys.compliance.detail(tenantId, recordId), data);
      // Invalidate lists
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.compliance.lists() });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.dashboard(tenantId) });
    },
    ...options,
  });
};

// Temperature Mutations
export const useCreateTemperatureLog = (
  options?: UseMutationOptions<
    TemperatureLogResponse, 
    ApiError, 
    { tenantId: string; logData: TemperatureLogCreate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    TemperatureLogResponse, 
    ApiError, 
    { tenantId: string; logData: TemperatureLogCreate }
  >({
    mutationFn: ({ tenantId, logData }) => foodSafetyService.createTemperatureLog(tenantId, logData),
    onSuccess: (data, { tenantId }) => {
      // Invalidate temperature queries
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.temperature.lists() });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.dashboard(tenantId) });
      
      // If alert was triggered, invalidate alerts
      if (data.alert_triggered) {
        queryClient.invalidateQueries({ queryKey: foodSafetyKeys.alerts.lists() });
      }
    },
    ...options,
  });
};

export const useCreateBulkTemperatureLogs = (
  options?: UseMutationOptions<
    { created_count: number; failed_count: number; errors?: string[] }, 
    ApiError, 
    { tenantId: string; bulkData: BulkTemperatureLogCreate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    { created_count: number; failed_count: number; errors?: string[] }, 
    ApiError, 
    { tenantId: string; bulkData: BulkTemperatureLogCreate }
  >({
    mutationFn: ({ tenantId, bulkData }) => foodSafetyService.createBulkTemperatureLogs(tenantId, bulkData),
    onSuccess: (data, { tenantId }) => {
      // Invalidate temperature queries
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.temperature.lists() });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.dashboard(tenantId) });
    },
    ...options,
  });
};

// Alert Mutations
export const useCreateFoodSafetyAlert = (
  options?: UseMutationOptions<
    FoodSafetyAlertResponse, 
    ApiError, 
    { tenantId: string; alertData: FoodSafetyAlertCreate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    FoodSafetyAlertResponse, 
    ApiError, 
    { tenantId: string; alertData: FoodSafetyAlertCreate }
  >({
    mutationFn: ({ tenantId, alertData }) => foodSafetyService.createFoodSafetyAlert(tenantId, alertData),
    onSuccess: (data, { tenantId }) => {
      // Add to cache
      queryClient.setQueryData(foodSafetyKeys.alerts.detail(tenantId, data.id), data);
      // Invalidate lists
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.alerts.lists() });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.dashboard(tenantId) });
    },
    ...options,
  });
};

export const useUpdateFoodSafetyAlert = (
  options?: UseMutationOptions<
    FoodSafetyAlertResponse, 
    ApiError, 
    { tenantId: string; alertId: string; updateData: FoodSafetyAlertUpdate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    FoodSafetyAlertResponse, 
    ApiError, 
    { tenantId: string; alertId: string; updateData: FoodSafetyAlertUpdate }
  >({
    mutationFn: ({ tenantId, alertId, updateData }) => 
      foodSafetyService.updateFoodSafetyAlert(tenantId, alertId, updateData),
    onSuccess: (data, { tenantId, alertId }) => {
      // Update cache
      queryClient.setQueryData(foodSafetyKeys.alerts.detail(tenantId, alertId), data);
      // Invalidate lists
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.alerts.lists() });
      queryClient.invalidateQueries({ queryKey: foodSafetyKeys.dashboard(tenantId) });
    },
    ...options,
  });
};