/**
 * Suppliers React Query hooks
 * Provides data fetching, caching, and state management for supplier operations
 */

import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { suppliersService } from '../services/suppliers';
import { ApiError } from '../client/apiClient';
import type {
  SupplierCreate,
  SupplierUpdate,
  SupplierResponse,
  SupplierSummary,
  SupplierApproval,
  SupplierSearchParams,
  SupplierStatistics,
  SupplierDeletionSummary,
  DeliveryCreate,
  DeliveryUpdate,
  DeliveryResponse,
  DeliveryReceiptConfirmation,
  DeliverySearchParams,
  PerformanceMetric,
  SupplierPriceListCreate,
  SupplierPriceListUpdate,
  SupplierPriceListResponse,
} from '../types/suppliers';

// Query Keys Factory
export const suppliersKeys = {
  all: ['suppliers'] as const,
  suppliers: {
    all: () => [...suppliersKeys.all, 'suppliers'] as const,
    lists: () => [...suppliersKeys.suppliers.all(), 'list'] as const,
    list: (tenantId: string, params?: SupplierSearchParams) => 
      [...suppliersKeys.suppliers.lists(), tenantId, params] as const,
    details: () => [...suppliersKeys.suppliers.all(), 'detail'] as const,
    detail: (tenantId: string, supplierId: string) => 
      [...suppliersKeys.suppliers.details(), tenantId, supplierId] as const,
    statistics: (tenantId: string) => 
      [...suppliersKeys.suppliers.all(), 'statistics', tenantId] as const,
    top: (tenantId: string) => 
      [...suppliersKeys.suppliers.all(), 'top', tenantId] as const,
    byType: (tenantId: string, supplierType: string) => 
      [...suppliersKeys.suppliers.all(), 'by-type', tenantId, supplierType] as const,
  },
  deliveries: {
    all: () => [...suppliersKeys.all, 'deliveries'] as const,
    lists: () => [...suppliersKeys.deliveries.all(), 'list'] as const,
    list: (params?: DeliverySearchParams) => 
      [...suppliersKeys.deliveries.lists(), params] as const,
    details: () => [...suppliersKeys.deliveries.all(), 'detail'] as const,
    detail: (deliveryId: string) => 
      [...suppliersKeys.deliveries.details(), deliveryId] as const,
  },
  performance: {
    all: () => [...suppliersKeys.all, 'performance'] as const,
    metrics: (tenantId: string, supplierId: string) => 
      [...suppliersKeys.performance.all(), 'metrics', tenantId, supplierId] as const,
    alerts: (tenantId: string, supplierId?: string) => 
      [...suppliersKeys.performance.all(), 'alerts', tenantId, supplierId] as const,
  },
} as const;

// Supplier Queries
export const useSuppliers = (
  tenantId: string,
  queryParams?: SupplierSearchParams,
  options?: Omit<UseQueryOptions<SupplierSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierSummary[], ApiError>({
    queryKey: suppliersKeys.suppliers.list(tenantId, queryParams),
    queryFn: () => suppliersService.getSuppliers(tenantId, queryParams),
    enabled: !!tenantId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

export const useSupplier = (
  tenantId: string,
  supplierId: string,
  options?: Omit<UseQueryOptions<SupplierResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierResponse, ApiError>({
    queryKey: suppliersKeys.suppliers.detail(tenantId, supplierId),
    queryFn: () => suppliersService.getSupplier(tenantId, supplierId),
    enabled: !!tenantId && !!supplierId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useSupplierStatistics = (
  tenantId: string,
  options?: Omit<UseQueryOptions<SupplierStatistics, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierStatistics, ApiError>({
    queryKey: suppliersKeys.suppliers.statistics(tenantId),
    queryFn: () => suppliersService.getSupplierStatistics(tenantId),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useActiveSuppliers = (
  tenantId: string,
  queryParams?: Omit<SupplierSearchParams, 'status'>,
  options?: Omit<UseQueryOptions<SupplierSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierSummary[], ApiError>({
    queryKey: suppliersKeys.suppliers.list(tenantId, { ...queryParams }),
    queryFn: () => suppliersService.getActiveSuppliers(tenantId, queryParams),
    enabled: !!tenantId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

export const useTopSuppliers = (
  tenantId: string,
  options?: Omit<UseQueryOptions<SupplierResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierResponse[], ApiError>({
    queryKey: suppliersKeys.suppliers.top(tenantId),
    queryFn: () => suppliersService.getTopSuppliers(tenantId),
    enabled: !!tenantId,
    staleTime: 10 * 60 * 1000, // 10 minutes
    ...options,
  });
};

export const usePendingApprovalSuppliers = (
  tenantId: string,
  options?: Omit<UseQueryOptions<SupplierSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierSummary[], ApiError>({
    queryKey: suppliersKeys.suppliers.list(tenantId, {}),
    queryFn: () => suppliersService.getPendingApprovalSuppliers(tenantId),
    enabled: !!tenantId,
    staleTime: 1 * 60 * 1000, // 1 minute
    ...options,
  });
};

export const useSuppliersByType = (
  tenantId: string,
  supplierType: string,
  queryParams?: Omit<SupplierSearchParams, 'supplier_type'>,
  options?: Omit<UseQueryOptions<SupplierSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierSummary[], ApiError>({
    queryKey: suppliersKeys.suppliers.byType(tenantId, supplierType),
    queryFn: () => suppliersService.getSuppliersByType(tenantId, supplierType, queryParams),
    enabled: !!tenantId && !!supplierType,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

// Delivery Queries
export const useDeliveries = (
  tenantId: string,
  queryParams?: DeliverySearchParams,
  options?: Omit<UseQueryOptions<DeliveryResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<DeliveryResponse[], ApiError>({
    queryKey: suppliersKeys.deliveries.list(queryParams),
    queryFn: () => suppliersService.getDeliveries(tenantId, queryParams as any),
    enabled: !!tenantId,
    staleTime: 1 * 60 * 1000, // 1 minute
    ...options,
  });
};

export const useDelivery = (
  tenantId: string,
  deliveryId: string,
  options?: Omit<UseQueryOptions<DeliveryResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<DeliveryResponse, ApiError>({
    queryKey: suppliersKeys.deliveries.detail(deliveryId),
    queryFn: () => suppliersService.getDelivery(tenantId, deliveryId),
    enabled: !!tenantId && !!deliveryId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

// Supplier Price List Queries
export const useSupplierPriceLists = (
  tenantId: string,
  supplierId: string,
  isActive: boolean = true,
  options?: Omit<UseQueryOptions<SupplierPriceListResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierPriceListResponse[], ApiError>({
    queryKey: [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-lists', isActive],
    queryFn: () => suppliersService.getSupplierPriceLists(tenantId, supplierId, isActive),
    enabled: !!tenantId && !!supplierId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useSupplierPriceList = (
  tenantId: string,
  supplierId: string,
  priceListId: string,
  options?: Omit<UseQueryOptions<SupplierPriceListResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SupplierPriceListResponse, ApiError>({
    queryKey: [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-list', priceListId],
    queryFn: () => suppliersService.getSupplierPriceList(tenantId, supplierId, priceListId),
    enabled: !!tenantId && !!supplierId && !!priceListId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

// Performance Queries
export const useSupplierPerformanceMetrics = (
  tenantId: string,
  supplierId: string,
  options?: Omit<UseQueryOptions<PerformanceMetric[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PerformanceMetric[], ApiError>({
    queryKey: suppliersKeys.performance.metrics(tenantId, supplierId),
    queryFn: () => suppliersService.getSupplierPerformanceMetrics(tenantId, supplierId),
    enabled: !!tenantId && !!supplierId,
    staleTime: 10 * 60 * 1000, // 10 minutes
    ...options,
  });
};

export const usePerformanceAlerts = (
  tenantId: string,
  supplierId?: string,
  options?: Omit<UseQueryOptions<any[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<any[], ApiError>({
    queryKey: suppliersKeys.performance.alerts(tenantId, supplierId),
    queryFn: () => suppliersService.getPerformanceAlerts(tenantId, supplierId),
    enabled: !!tenantId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

// Supplier Mutations
export const useCreateSupplier = (
  options?: UseMutationOptions<
    SupplierResponse,
    ApiError,
    { tenantId: string; supplierData: SupplierCreate }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    SupplierResponse,
    ApiError,
    { tenantId: string; supplierData: SupplierCreate }
  >({
    mutationFn: ({ tenantId, supplierData }) =>
      suppliersService.createSupplier(tenantId, supplierData),
    onSuccess: (data, { tenantId }) => {
      // Add to cache
      queryClient.setQueryData(
        suppliersKeys.suppliers.detail(tenantId, data.id),
        data
      );
      
      // Invalidate lists and statistics
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.lists()
      });
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.statistics(tenantId)
      });
    },
    ...options,
  });
};

export const useUpdateSupplier = (
  options?: UseMutationOptions<
    SupplierResponse,
    ApiError,
    { tenantId: string; supplierId: string; updateData: SupplierUpdate }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    SupplierResponse,
    ApiError,
    { tenantId: string; supplierId: string; updateData: SupplierUpdate }
  >({
    mutationFn: ({ tenantId, supplierId, updateData }) =>
      suppliersService.updateSupplier(tenantId, supplierId, updateData),
    onSuccess: (data, { tenantId, supplierId }) => {
      // Update cache
      queryClient.setQueryData(
        suppliersKeys.suppliers.detail(tenantId, supplierId),
        data
      );
      
      // Invalidate lists
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.lists()
      });
    },
    ...options,
  });
};

export const useApproveSupplier = (
  options?: UseMutationOptions<
    SupplierResponse,
    ApiError,
    { tenantId: string; supplierId: string; approvalData: SupplierApproval }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    SupplierResponse,
    ApiError,
    { tenantId: string; supplierId: string; approvalData: SupplierApproval }
  >({
    mutationFn: ({ tenantId, supplierId, approvalData }) =>
      suppliersService.approveSupplier(tenantId, supplierId, approvalData),
    onSuccess: (data, { tenantId, supplierId }) => {
      // Update cache with new supplier status
      queryClient.setQueryData(
        suppliersKeys.suppliers.detail(tenantId, supplierId),
        data
      );

      // Invalidate lists and statistics as approval changes counts
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.lists()
      });
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.statistics(tenantId)
      });
    },
    ...options,
  });
};

export const useDeleteSupplier = (
  options?: UseMutationOptions<
    { message: string },
    ApiError,
    { tenantId: string; supplierId: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    { message: string },
    ApiError,
    { tenantId: string; supplierId: string }
  >({
    mutationFn: ({ tenantId, supplierId }) =>
      suppliersService.deleteSupplier(tenantId, supplierId),
    onSuccess: (_, { tenantId, supplierId }) => {
      // Remove from cache
      queryClient.removeQueries({
        queryKey: suppliersKeys.suppliers.detail(tenantId, supplierId)
      });
      
      // Invalidate lists and statistics
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.lists()
      });
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.statistics(tenantId)
      });
    },
    ...options,
  });
};

export const useHardDeleteSupplier = (
  options?: UseMutationOptions<
    SupplierDeletionSummary,
    ApiError,
    { tenantId: string; supplierId: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    SupplierDeletionSummary,
    ApiError,
    { tenantId: string; supplierId: string }
  >({
    mutationFn: ({ tenantId, supplierId }) =>
      suppliersService.hardDeleteSupplier(tenantId, supplierId),
    onSuccess: (_, { tenantId, supplierId }) => {
      // Remove from cache
      queryClient.removeQueries({
        queryKey: suppliersKeys.suppliers.detail(tenantId, supplierId)
      });

      // Invalidate lists and statistics
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.lists()
      });
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.suppliers.statistics(tenantId)
      });
    },
    ...options,
  });
};

// Delivery Mutations
export const useCreateDelivery = (
  options?: UseMutationOptions<DeliveryResponse, ApiError, DeliveryCreate>
) => {
  const queryClient = useQueryClient();

  return useMutation<DeliveryResponse, ApiError, DeliveryCreate>({
    mutationFn: (deliveryData) => suppliersService.createDelivery(deliveryData),
    onSuccess: (data) => {
      // Add to cache
      queryClient.setQueryData(
        suppliersKeys.deliveries.detail(data.id),
        data
      );
      
      // Invalidate lists
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.deliveries.lists()
      });
    },
    ...options,
  });
};

export const useUpdateDelivery = (
  options?: UseMutationOptions<
    DeliveryResponse,
    ApiError,
    { deliveryId: string; updateData: DeliveryUpdate }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    DeliveryResponse,
    ApiError,
    { deliveryId: string; updateData: DeliveryUpdate }
  >({
    mutationFn: ({ deliveryId, updateData }) =>
      suppliersService.updateDelivery(deliveryId, updateData),
    onSuccess: (data, { deliveryId }) => {
      // Update cache
      queryClient.setQueryData(
        suppliersKeys.deliveries.detail(deliveryId),
        data
      );
      
      // Invalidate lists
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.deliveries.lists()
      });
    },
    ...options,
  });
};

export const useConfirmDeliveryReceipt = (
  options?: UseMutationOptions<
    DeliveryResponse,
    ApiError,
    { deliveryId: string; confirmation: DeliveryReceiptConfirmation }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    DeliveryResponse,
    ApiError,
    { deliveryId: string; confirmation: DeliveryReceiptConfirmation }
  >({
    mutationFn: ({ deliveryId, confirmation }) =>
      suppliersService.confirmDeliveryReceipt(deliveryId, confirmation),
    onSuccess: (data, { deliveryId }) => {
      // Update cache
      queryClient.setQueryData(
        suppliersKeys.deliveries.detail(deliveryId),
        data
      );
      
      // Invalidate lists and performance metrics
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.deliveries.lists()
      });
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.performance.all()
      });
    },
    ...options,
  });
};

// Supplier Price List Mutations
export const useCreateSupplierPriceList = (
  options?: UseMutationOptions<
    SupplierPriceListResponse,
    ApiError,
    { tenantId: string; supplierId: string; priceListData: SupplierPriceListCreate }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    SupplierPriceListResponse,
    ApiError,
    { tenantId: string; supplierId: string; priceListData: SupplierPriceListCreate }
  >({
    mutationFn: ({ tenantId, supplierId, priceListData }) =>
      suppliersService.createSupplierPriceList(tenantId, supplierId, priceListData),
    onSuccess: (data, { tenantId, supplierId }) => {
      // Add to cache
      queryClient.setQueryData(
        [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-list', data.id],
        data
      );
      
      // Invalidate price lists
      queryClient.invalidateQueries({
        queryKey: [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-lists']
      });
    },
    ...options,
  });
};

export const useUpdateSupplierPriceList = (
  options?: UseMutationOptions<
    SupplierPriceListResponse,
    ApiError,
    { tenantId: string; supplierId: string; priceListId: string; priceListData: SupplierPriceListUpdate }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    SupplierPriceListResponse,
    ApiError,
    { tenantId: string; supplierId: string; priceListId: string; priceListData: SupplierPriceListUpdate }
  >({
    mutationFn: ({ tenantId, supplierId, priceListId, priceListData }) =>
      suppliersService.updateSupplierPriceList(tenantId, supplierId, priceListId, priceListData),
    onSuccess: (data, { tenantId, supplierId, priceListId }) => {
      // Update cache
      queryClient.setQueryData(
        [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-list', priceListId],
        data
      );
      
      // Invalidate price lists
      queryClient.invalidateQueries({
        queryKey: [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-lists']
      });
    },
    ...options,
  });
};

export const useDeleteSupplierPriceList = (
  options?: UseMutationOptions<
    { message: string },
    ApiError,
    { tenantId: string; supplierId: string; priceListId: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    { message: string },
    ApiError,
    { tenantId: string; supplierId: string; priceListId: string }
  >({
    mutationFn: ({ tenantId, supplierId, priceListId }) =>
      suppliersService.deleteSupplierPriceList(tenantId, supplierId, priceListId),
    onSuccess: (_, { tenantId, supplierId, priceListId }) => {
      // Remove from cache
      queryClient.removeQueries({
        queryKey: [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-list', priceListId]
      });
      
      // Invalidate price lists
      queryClient.invalidateQueries({
        queryKey: [...suppliersKeys.suppliers.detail(tenantId, supplierId), 'price-lists']
      });
    },
    ...options,
  });
};

// Performance Mutations
export const useCalculateSupplierPerformance = (
  options?: UseMutationOptions<
    { message: string; calculation_id: string },
    ApiError,
    { tenantId: string; supplierId: string; request?: any }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    { message: string; calculation_id: string },
    ApiError,
    { tenantId: string; supplierId: string; request?: any }
  >({
    mutationFn: ({ tenantId, supplierId, request }) =>
      suppliersService.calculateSupplierPerformance(tenantId, supplierId, request),
    onSuccess: (_, { tenantId, supplierId }) => {
      // Invalidate performance metrics after calculation
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.performance.metrics(tenantId, supplierId)
      });
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.performance.alerts(tenantId)
      });
    },
    ...options,
  });
};

export const useEvaluatePerformanceAlerts = (
  options?: UseMutationOptions<
    { alerts_generated: number; message: string },
    ApiError,
    { tenantId: string; supplierId?: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    { alerts_generated: number; message: string },
    ApiError,
    { tenantId: string; supplierId?: string }
  >({
    mutationFn: ({ tenantId, supplierId }) => suppliersService.evaluatePerformanceAlerts(tenantId, supplierId),
    onSuccess: (_, { tenantId }) => {
      // Invalidate performance alerts
      queryClient.invalidateQueries({
        queryKey: suppliersKeys.performance.alerts(tenantId)
      });
    },
    ...options,
  });
};

// Utility Hooks
export const useSuppliersByStatus = (tenantId: string, status: string) => {
  return useSuppliers(tenantId, { status: status as any });
};

export const useSuppliersCount = (tenantId: string) => {
  const { data: statistics } = useSupplierStatistics(tenantId);
  return statistics?.total_suppliers || 0;
};

export const useActiveSuppliersCount = (tenantId: string) => {
  const { data: statistics } = useSupplierStatistics(tenantId);
  return statistics?.active_suppliers || 0;
};

export const usePendingOrdersCount = (queryParams?: PurchaseOrderSearchParams) => {
  const { data: orders } = usePurchaseOrders('', queryParams);
  return orders?.length || 0;
};
