/**
 * Purchase Orders React Query hooks
 * Handles data fetching and mutations for purchase orders
 */

import { useQuery, useMutation, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { ApiError } from '../client/apiClient';
import type {
  PurchaseOrderSummary,
  PurchaseOrderDetail,
  PurchaseOrderSearchParams,
  PurchaseOrderUpdateData,
  PurchaseOrderCreateData,
  PurchaseOrderStatus,
  CreateDeliveryInput,
  DeliveryResponse
} from '../services/purchase_orders';
import {
  listPurchaseOrders,
  getPurchaseOrder,
  getPendingApprovalPurchaseOrders,
  getPurchaseOrdersByStatus,
  createPurchaseOrder,
  updatePurchaseOrder,
  approvePurchaseOrder,
  rejectPurchaseOrder,
  bulkApprovePurchaseOrders,
  deletePurchaseOrder,
  createDelivery
} from '../services/purchase_orders';

// Query Keys
export const purchaseOrderKeys = {
  all: ['purchase-orders'] as const,
  lists: () => [...purchaseOrderKeys.all, 'list'] as const,
  list: (tenantId: string, params?: PurchaseOrderSearchParams) =>
    [...purchaseOrderKeys.lists(), tenantId, params] as const,
  details: () => [...purchaseOrderKeys.all, 'detail'] as const,
  detail: (tenantId: string, poId: string) =>
    [...purchaseOrderKeys.details(), tenantId, poId] as const,
  byStatus: (tenantId: string, status: PurchaseOrderStatus) =>
    [...purchaseOrderKeys.lists(), tenantId, 'status', status] as const,
  pendingApproval: (tenantId: string) =>
    [...purchaseOrderKeys.lists(), tenantId, 'pending-approval'] as const,
} as const;

/**
 * Hook to list purchase orders with optional filters
 */
export const usePurchaseOrders = (
  tenantId: string,
  params?: PurchaseOrderSearchParams,
  options?: Omit<UseQueryOptions<PurchaseOrderSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PurchaseOrderSummary[], ApiError>({
    queryKey: purchaseOrderKeys.list(tenantId, params),
    queryFn: () => listPurchaseOrders(tenantId, params),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

/**
 * Hook to get pending approval purchase orders
 */
export const usePendingApprovalPurchaseOrders = (
  tenantId: string,
  limit: number = 50,
  options?: Omit<UseQueryOptions<PurchaseOrderSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PurchaseOrderSummary[], ApiError>({
    queryKey: purchaseOrderKeys.pendingApproval(tenantId),
    queryFn: () => getPendingApprovalPurchaseOrders(tenantId, limit),
    enabled: !!tenantId,
    staleTime: 15 * 1000, // 15 seconds - more frequent for pending approvals
    refetchInterval: 30 * 1000, // Auto-refetch every 30 seconds
    ...options,
  });
};

/**
 * Hook to get purchase orders by status
 */
export const usePurchaseOrdersByStatus = (
  tenantId: string,
  status: PurchaseOrderStatus,
  limit: number = 50,
  options?: Omit<UseQueryOptions<PurchaseOrderSummary[], ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PurchaseOrderSummary[], ApiError>({
    queryKey: purchaseOrderKeys.byStatus(tenantId, status),
    queryFn: () => getPurchaseOrdersByStatus(tenantId, status, limit),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

/**
 * Hook to get a single purchase order detail
 */
export const usePurchaseOrder = (
  tenantId: string,
  poId: string,
  options?: Omit<UseQueryOptions<PurchaseOrderDetail, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<PurchaseOrderDetail, ApiError>({
    queryKey: purchaseOrderKeys.detail(tenantId, poId),
    queryFn: () => getPurchaseOrder(tenantId, poId),
    enabled: !!tenantId && !!poId,
    staleTime: 30 * 1000, // 30 seconds
    ...options,
  });
};

/**
 * Hook to create a new purchase order
 */
export const useCreatePurchaseOrder = (
  options?: UseMutationOptions<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; data: PurchaseOrderCreateData }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; data: PurchaseOrderCreateData }
  >({
    mutationFn: ({ tenantId, data }) => createPurchaseOrder(tenantId, data),
    onSuccess: (data, variables) => {
      // Invalidate all lists to refresh with new PO
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.lists() });
      // Add to cache
      queryClient.setQueryData(
        purchaseOrderKeys.detail(variables.tenantId, data.id),
        data
      );
    },
    ...options,
  });
};

/**
 * Hook to update a purchase order
 */
export const useUpdatePurchaseOrder = (
  options?: UseMutationOptions<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; poId: string; data: PurchaseOrderUpdateData }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; poId: string; data: PurchaseOrderUpdateData }
  >({
    mutationFn: ({ tenantId, poId, data }) => updatePurchaseOrder(tenantId, poId, data),
    onSuccess: (data, variables) => {
      // Invalidate and refetch related queries
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.lists() });
      queryClient.invalidateQueries({
        queryKey: purchaseOrderKeys.detail(variables.tenantId, variables.poId)
      });
    },
    ...options,
  });
};

/**
 * Hook to approve a purchase order
 */
export const useApprovePurchaseOrder = (
  options?: UseMutationOptions<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; poId: string; notes?: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; poId: string; notes?: string }
  >({
    mutationFn: ({ tenantId, poId, notes }) => approvePurchaseOrder(tenantId, poId, notes),
    onSuccess: (data, variables) => {
      // Invalidate pending approvals list
      queryClient.invalidateQueries({
        queryKey: purchaseOrderKeys.pendingApproval(variables.tenantId)
      });
      // Invalidate all lists
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.lists() });
      // Invalidate detail
      queryClient.invalidateQueries({
        queryKey: purchaseOrderKeys.detail(variables.tenantId, variables.poId)
      });
    },
    ...options,
  });
};

/**
 * Hook to reject a purchase order
 */
export const useRejectPurchaseOrder = (
  options?: UseMutationOptions<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; poId: string; reason: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    PurchaseOrderDetail,
    ApiError,
    { tenantId: string; poId: string; reason: string }
  >({
    mutationFn: ({ tenantId, poId, reason }) => rejectPurchaseOrder(tenantId, poId, reason),
    onSuccess: (data, variables) => {
      // Invalidate pending approvals list
      queryClient.invalidateQueries({
        queryKey: purchaseOrderKeys.pendingApproval(variables.tenantId)
      });
      // Invalidate all lists
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.lists() });
      // Invalidate detail
      queryClient.invalidateQueries({
        queryKey: purchaseOrderKeys.detail(variables.tenantId, variables.poId)
      });
    },
    ...options,
  });
};

/**
 * Hook to bulk approve purchase orders
 */
export const useBulkApprovePurchaseOrders = (
  options?: UseMutationOptions<
    PurchaseOrderDetail[],
    ApiError,
    { tenantId: string; poIds: string[]; notes?: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    PurchaseOrderDetail[],
    ApiError,
    { tenantId: string; poIds: string[]; notes?: string }
  >({
    mutationFn: ({ tenantId, poIds, notes }) => bulkApprovePurchaseOrders(tenantId, poIds, notes),
    onSuccess: (data, variables) => {
      // Invalidate all PO queries
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.all });
    },
    ...options,
  });
};

/**
 * Hook to delete a purchase order
 */
export const useDeletePurchaseOrder = (
  options?: UseMutationOptions<
    { message: string },
    ApiError,
    { tenantId: string; poId: string }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    { message: string },
    ApiError,
    { tenantId: string; poId: string }
  >({
    mutationFn: ({ tenantId, poId }) => deletePurchaseOrder(tenantId, poId),
    onSuccess: (data, variables) => {
      // Invalidate all PO queries
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.all });
    },
    ...options,
  });
};

/**
 * Hook to create a delivery for a purchase order
 */
export const useCreateDelivery = (
  options?: UseMutationOptions<
    DeliveryResponse,
    ApiError,
    { tenantId: string; poId: string; deliveryData: CreateDeliveryInput }
  >
) => {
  const queryClient = useQueryClient();

  return useMutation<
    DeliveryResponse,
    ApiError,
    { tenantId: string; poId: string; deliveryData: CreateDeliveryInput }
  >({
    mutationFn: ({ tenantId, poId, deliveryData }) => createDelivery(tenantId, poId, deliveryData),
    onSuccess: (data, variables) => {
      // Invalidate all PO queries to refresh status
      queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.all });
      // Invalidate detail for this specific PO
      queryClient.invalidateQueries({
        queryKey: purchaseOrderKeys.detail(variables.tenantId, variables.poId)
      });
    },
    ...options,
  });
};
