/**
 * Production React Query hooks
 */
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { productionService } from '../services/production';
import type {
  ProductionBatchCreate,
  ProductionBatchStatusUpdate,
  ProductionBatchResponse,
  ProductionBatchListResponse,
  ProductionDashboardSummary,
  DailyProductionRequirements,
  ProductionScheduleUpdate,
  ProductionCapacityStatus,
  ProductionYieldMetrics,
} from '../types/production';
import { ApiError } from '../client';

// Query Keys
export const productionKeys = {
  all: ['production'] as const,
  tenant: (tenantId: string) => [...productionKeys.all, tenantId] as const,
  dashboard: (tenantId: string) => [...productionKeys.tenant(tenantId), 'dashboard'] as const,
  dailyRequirements: (tenantId: string, date?: string) => 
    [...productionKeys.tenant(tenantId), 'daily-requirements', date] as const,
  requirements: (tenantId: string, date?: string) => 
    [...productionKeys.tenant(tenantId), 'requirements', date] as const,
  batches: (tenantId: string) => [...productionKeys.tenant(tenantId), 'batches'] as const,
  activeBatches: (tenantId: string) => [...productionKeys.batches(tenantId), 'active'] as const,
  batch: (tenantId: string, batchId: string) => 
    [...productionKeys.batches(tenantId), batchId] as const,
  schedule: (tenantId: string, startDate?: string, endDate?: string) => 
    [...productionKeys.tenant(tenantId), 'schedule', startDate, endDate] as const,
  capacity: (tenantId: string, date?: string) => 
    [...productionKeys.tenant(tenantId), 'capacity', date] as const,
  yieldMetrics: (tenantId: string, startDate: string, endDate: string) => 
    [...productionKeys.tenant(tenantId), 'yield-metrics', startDate, endDate] as const,
} as const;

// Dashboard Queries
export const useProductionDashboard = (
  tenantId: string,
  options?: Omit<UseQueryOptions<ProductionDashboardSummary, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<ProductionDashboardSummary, ApiError>({
    queryKey: productionKeys.dashboard(tenantId),
    queryFn: () => productionService.getDashboardSummary(tenantId),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    refetchInterval: 60 * 1000, // 1 minute
    ...options,
  });
};

export const useDailyProductionRequirements = (
  tenantId: string,
  date?: string,
  options?: Omit<UseQueryOptions<any, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<any, ApiError>({
    queryKey: productionKeys.dailyRequirements(tenantId, date),
    queryFn: () => productionService.getDailyProductionPlan(tenantId, date),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useProductionRequirements = (
  tenantId: string,
  date?: string,
  options?: Omit<UseQueryOptions<any, ApiError>, 'queryKey' | 'queryFn'>
) => {
  const queryDate = date || new Date().toISOString().split('T')[0];

  return useQuery<any, ApiError>({
    queryKey: productionKeys.requirements(tenantId, date),
    queryFn: () => productionService.getProductionRequirements(tenantId, queryDate),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

// Batch Queries
export const useActiveBatches = (
  tenantId: string,
  options?: Omit<UseQueryOptions<ProductionBatchListResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<ProductionBatchListResponse, ApiError>({
    queryKey: productionKeys.activeBatches(tenantId),
    queryFn: () => productionService.getBatches(tenantId, {
      status: undefined // Get all active statuses
    }),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    refetchInterval: 60 * 1000, // 1 minute
    ...options,
  });
};

export const useBatchDetails = (
  tenantId: string,
  batchId: string,
  options?: Omit<UseQueryOptions<ProductionBatchResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<ProductionBatchResponse, ApiError>({
    queryKey: productionKeys.batch(tenantId, batchId),
    queryFn: () => productionService.getBatch(tenantId, batchId),
    enabled: !!tenantId && !!batchId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

// Schedule and Capacity Queries
export const useProductionSchedule = (
  tenantId: string,
  startDate?: string,
  endDate?: string,
  options?: Omit<UseQueryOptions<any, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<any, ApiError>({
    queryKey: productionKeys.schedule(tenantId, startDate, endDate),
    queryFn: () => productionService.getSchedules(tenantId, { start_date: startDate, end_date: endDate }),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useCapacityStatus = (
  tenantId: string,
  date?: string,
  options?: Omit<UseQueryOptions<any, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<any, ApiError>({
    queryKey: productionKeys.capacity(tenantId, date),
    queryFn: () => date ? productionService.getCapacityByDate(tenantId, date) : productionService.getCapacity(tenantId),
    enabled: !!tenantId,
    staleTime: 5 * 60 * 1000, // 5 minutes
    ...options,
  });
};

export const useYieldMetrics = (
  tenantId: string,
  startDate: string,
  endDate: string,
  options?: Omit<UseQueryOptions<any, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<any, ApiError>({
    queryKey: productionKeys.yieldMetrics(tenantId, startDate, endDate),
    queryFn: () => productionService.getYieldTrends(tenantId),
    enabled: !!tenantId,
    staleTime: 15 * 60 * 1000, // 15 minutes (metrics are less frequently changing)
    ...options,
  });
};

// Mutations
export const useCreateProductionBatch = (
  options?: UseMutationOptions<ProductionBatchResponse, ApiError, { tenantId: string; batchData: ProductionBatchCreate }>
) => {
  const queryClient = useQueryClient();

  return useMutation<ProductionBatchResponse, ApiError, { tenantId: string; batchData: ProductionBatchCreate }>({
    mutationFn: ({ tenantId, batchData }) => productionService.createBatch(tenantId, batchData),
    onSuccess: (data, { tenantId }) => {
      // Invalidate active batches to refresh the list
      queryClient.invalidateQueries({ queryKey: productionKeys.activeBatches(tenantId) });
      // Invalidate dashboard to update summary
      queryClient.invalidateQueries({ queryKey: productionKeys.dashboard(tenantId) });
      // Cache the new batch details
      queryClient.setQueryData(productionKeys.batch(tenantId, data.id), data);
    },
    ...options,
  });
};

export const useUpdateBatchStatus = (
  options?: UseMutationOptions<
    ProductionBatchResponse, 
    ApiError, 
    { tenantId: string; batchId: string; statusUpdate: ProductionBatchStatusUpdate }
  >
) => {
  const queryClient = useQueryClient();
  
  return useMutation<
    ProductionBatchResponse, 
    ApiError, 
    { tenantId: string; batchId: string; statusUpdate: ProductionBatchStatusUpdate }
  >({
    mutationFn: ({ tenantId, batchId, statusUpdate }) =>
      productionService.updateBatchStatus(tenantId, batchId, statusUpdate),
    onSuccess: (data, { tenantId, batchId }) => {
      // Update the specific batch data
      queryClient.setQueryData(productionKeys.batch(tenantId, batchId), data);
      // Invalidate active batches to refresh the list
      queryClient.invalidateQueries({ queryKey: productionKeys.activeBatches(tenantId) });
      // Invalidate dashboard to update summary
      queryClient.invalidateQueries({ queryKey: productionKeys.dashboard(tenantId) });
    },
    ...options,
  });
};

// Helper hooks for common use cases
export const useProductionDashboardData = (tenantId: string) => {
  const dashboard = useProductionDashboard(tenantId);
  const activeBatches = useActiveBatches(tenantId);
  const dailyRequirements = useDailyProductionRequirements(tenantId);
  
  return {
    dashboard: dashboard.data,
    activeBatches: activeBatches.data,
    dailyRequirements: dailyRequirements.data,
    isLoading: dashboard.isLoading || activeBatches.isLoading || dailyRequirements.isLoading,
    error: dashboard.error || activeBatches.error || dailyRequirements.error,
    refetch: () => {
      dashboard.refetch();
      activeBatches.refetch();
      dailyRequirements.refetch();
    },
  };
};

export const useProductionPlanningData = (tenantId: string, date?: string) => {
  const schedule = useProductionSchedule(tenantId);
  const capacity = useCapacityStatus(tenantId, date);
  const requirements = useProductionRequirements(tenantId, date);

  return {
    schedule: schedule.data,
    capacity: capacity.data,
    requirements: requirements.data,
    isLoading: schedule.isLoading || capacity.isLoading || requirements.isLoading,
    error: schedule.error || capacity.error || requirements.error,
    refetch: () => {
      schedule.refetch();
      capacity.refetch();
      requirements.refetch();
    },
  };
};

// ===== Scheduler Mutations =====

/**
 * Hook to trigger production scheduler manually (for development/testing)
 */
export const useTriggerProductionScheduler = (
  options?: UseMutationOptions<
    { success: boolean; message: string; tenant_id: string },
    ApiError,
    string
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    { success: boolean; message: string; tenant_id: string },
    ApiError,
    string
  >({
    mutationFn: (tenantId: string) => productionService.triggerProductionScheduler(tenantId),
    onSuccess: (_, tenantId) => {
      // Invalidate all production queries for this tenant
      queryClient.invalidateQueries({
        queryKey: productionKeys.dashboard(tenantId),
      });
      queryClient.invalidateQueries({
        queryKey: productionKeys.batches(tenantId),
      });
      queryClient.invalidateQueries({
        queryKey: productionKeys.activeBatches(tenantId),
      });
    },
    ...options,
  });
};