/**
 * Sales React Query hooks
 */
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { salesService } from '../services/sales';
import {
  SalesDataCreate,
  SalesDataUpdate,
  SalesDataResponse,
  SalesDataQuery,
  SalesAnalytics,
} from '../types/sales';
import { ApiError } from '../client';

// Query Keys
export const salesKeys = {
  all: ['sales'] as const,
  lists: () => [...salesKeys.all, 'list'] as const,
  list: (tenantId: string, filters?: SalesDataQuery) => [...salesKeys.lists(), tenantId, filters] as const,
  details: () => [...salesKeys.all, 'detail'] as const,
  detail: (tenantId: string, recordId: string) => [...salesKeys.details(), tenantId, recordId] as const,
  analytics: (tenantId: string, startDate?: string, endDate?: string) => 
    [...salesKeys.all, 'analytics', tenantId, { startDate, endDate }] as const,
  productSales: (tenantId: string, productId: string, startDate?: string, endDate?: string) => 
    [...salesKeys.all, 'product-sales', tenantId, productId, { startDate, endDate }] as const,
  categories: (tenantId: string) => [...salesKeys.all, 'categories', tenantId] as const,
} as const;

// Queries
export const useSalesRecords = (
  tenantId: string,
  query?: SalesDataQuery,
  options?: Omit<UseQueryOptions<SalesDataResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SalesDataResponse[], ApiError>({
    queryKey: salesKeys.list(tenantId, query),
    queryFn: () => salesService.getSalesRecords(tenantId, query),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

export const useSalesRecord = (
  tenantId: string,
  recordId: string,
  options?: Omit<UseQueryOptions<SalesDataResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SalesDataResponse, ApiError>({
    queryKey: salesKeys.detail(tenantId, recordId),
    queryFn: () => salesService.getSalesRecord(tenantId, recordId),
    enabled: !!tenantId && !!recordId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

export const useSalesAnalytics = (
  tenantId: string,
  startDate?: string,
  endDate?: string,
  options?: Omit<UseQueryOptions<SalesAnalytics, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SalesAnalytics, ApiError>({
    queryKey: salesKeys.analytics(tenantId, startDate, endDate),
    queryFn: () => salesService.getSalesAnalytics(tenantId, startDate, endDate),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useProductSales = (
  tenantId: string,
  inventoryProductId: string,
  startDate?: string,
  endDate?: string,
  options?: Omit<UseQueryOptions<SalesDataResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<SalesDataResponse[], ApiError>({
    queryKey: salesKeys.productSales(tenantId, inventoryProductId, startDate, endDate),
    queryFn: () => salesService.getProductSales(tenantId, inventoryProductId, startDate, endDate),
    enabled: !!tenantId && !!inventoryProductId,
    staleTime: 2 * 60 * 1000, // 2 minutes
    ...options,
  });
};

export const useProductCategories = (
  tenantId: string,
  options?: Omit<UseQueryOptions<string[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<string[], ApiError>({
    queryKey: salesKeys.categories(tenantId),
    queryFn: () => salesService.getProductCategories(tenantId),
    enabled: !!tenantId,
    staleTime: 10 * 60 * 1000, // 10 minutes
    ...options,
  });
};

// Mutations
export const useCreateSalesRecord = (
  options?: UseMutationOptions<SalesDataResponse, ApiError, { tenantId: string; salesData: SalesDataCreate }>
) => {
  const queryClient = useQueryClient();
  
  return useMutation<SalesDataResponse, ApiError, { tenantId: string; salesData: SalesDataCreate }>({
    mutationFn: ({ tenantId, salesData }) => salesService.createSalesRecord(tenantId, salesData),
    onSuccess: (data, { tenantId }) => {
      // Invalidate sales lists to refresh data
      queryClient.invalidateQueries({ queryKey: salesKeys.lists() });
      queryClient.invalidateQueries({ queryKey: salesKeys.analytics(tenantId) });
      // Set the new record in cache
      queryClient.setQueryData(salesKeys.detail(tenantId, data.id), data);
    },
    ...options,
  });
};

export const useUpdateSalesRecord = (
  options?: UseMutationOptions<
    SalesDataResponse, 
    ApiError, 
    { tenantId: string; recordId: string; updateData: SalesDataUpdate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    SalesDataResponse, 
    ApiError, 
    { tenantId: string; recordId: string; updateData: SalesDataUpdate }
  >({
    mutationFn: ({ tenantId, recordId, updateData }) => 
      salesService.updateSalesRecord(tenantId, recordId, updateData),
    onSuccess: (data, { tenantId, recordId }) => {
      // Update the record cache
      queryClient.setQueryData(salesKeys.detail(tenantId, recordId), data);
      // Invalidate related queries
      queryClient.invalidateQueries({ queryKey: salesKeys.lists() });
      queryClient.invalidateQueries({ queryKey: salesKeys.analytics(tenantId) });
    },
    ...options,
  });
};

export const useDeleteSalesRecord = (
  options?: UseMutationOptions<{ message: string }, ApiError, { tenantId: string; recordId: string }>
) => {
  const queryClient = useQueryClient();
  
  return useMutation<{ message: string }, ApiError, { tenantId: string; recordId: string }>({
    mutationFn: ({ tenantId, recordId }) => salesService.deleteSalesRecord(tenantId, recordId),
    onSuccess: (data, { tenantId, recordId }) => {
      // Remove from cache
      queryClient.removeQueries({ queryKey: salesKeys.detail(tenantId, recordId) });
      // Invalidate related queries
      queryClient.invalidateQueries({ queryKey: salesKeys.lists() });
      queryClient.invalidateQueries({ queryKey: salesKeys.analytics(tenantId) });
    },
    ...options,
  });
};

export const useValidateSalesRecord = (
  options?: UseMutationOptions<
    SalesDataResponse, 
    ApiError, 
    { tenantId: string; recordId: string; validationNotes?: string }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    SalesDataResponse, 
    ApiError, 
    { tenantId: string; recordId: string; validationNotes?: string }
  >({
    mutationFn: ({ tenantId, recordId, validationNotes }) => 
      salesService.validateSalesRecord(tenantId, recordId, validationNotes),
    onSuccess: (data, { tenantId, recordId }) => {
      // Update the record cache
      queryClient.setQueryData(salesKeys.detail(tenantId, recordId), data);
      // Invalidate sales lists to reflect validation status
      queryClient.invalidateQueries({ queryKey: salesKeys.lists() });
    },
    ...options,
  });
};
// Import/Export operations
export const useValidateImportFile = (
  options?: UseMutationOptions<any, ApiError, { tenantId: string; file: File }>
) => {
  return useMutation<any, ApiError, { tenantId: string; file: File }>({
    mutationFn: ({ tenantId, file }) => salesService.validateImportFile(tenantId, file),
    ...options,
  });
};

export const useImportSalesData = (
  options?: UseMutationOptions<any, ApiError, { tenantId: string; file: File }>
) => {
  const queryClient = useQueryClient();

  return useMutation<any, ApiError, { tenantId: string; file: File }>({
    mutationFn: ({ tenantId, file }) => salesService.importSalesData(tenantId, file),
    onSuccess: (data, { tenantId }) => {
      // Invalidate sales lists to include imported data
      queryClient.invalidateQueries({ queryKey: salesKeys.lists() });
      queryClient.invalidateQueries({ queryKey: salesKeys.analytics(tenantId) });
    },
    ...options,
  });
};
