import { useState, useCallback } from 'react';
import { notification } from 'antd';

export interface BatchUpdateResult {
  successIds: React.Key[];
  failedIds: React.Key[];
  successCount: number;
  failedCount: number;
}

export interface UseBatchUpdateConfig {
  resourceName: string;
  apiUrl: string;
  requestHeaders?: () => Record<string, string>;
  /** Called after all updates complete (regardless of success/failure) */
  onComplete?: (result: BatchUpdateResult) => void;
  /** Called only when at least one update succeeds */
  onSuccess?: (result: BatchUpdateResult) => void;
  /** Called only when at least one update fails */
  onError?: (result: BatchUpdateResult) => void;
  /** i18n translation function */
  t?: (key: string, defaultValue?: string) => string;
  /** Whether to show notification (default: true) */
  showNotification?: boolean;
  /** Custom notification handler - if provided, replaces default notification */
  customNotification?: (result: BatchUpdateResult) => void;
  /** Custom update function - if provided, replaces default fetch */
  customUpdateFn?: (id: number, values: any) => Promise<void>;
}

export interface UseBatchUpdateResult {
  /** Update selected items and return failed IDs */
  updateSelectedItems: (
    selectedKeys: React.Key[],
    values: any,
  ) => Promise<React.Key[]>;
  /** Update a single item */
  updateOne: (id: number, values: any) => Promise<void>;
  /** Loading state */
  updateManyIsLoading: boolean;
}

/**
 * Hook for batch updating selected items
 *
 * @example
 * // Basic usage
 * const { updateSelectedItems, updateManyIsLoading } = useBatchUpdate({
 *   resourceName: 'audit',
 *   apiUrl: '/api',
 * });
 *
 * @example
 * // With custom notification
 * const { updateSelectedItems } = useBatchUpdate({
 *   resourceName: 'audit',
 *   apiUrl: '/api',
 *   showNotification: false,
 *   onComplete: (result) => {
 *     myCustomNotify(`Updated ${result.successCount} items`);
 *   },
 * });
 *
 * @example
 * // With custom update function
 * const { updateSelectedItems } = useBatchUpdate({
 *   resourceName: 'audit',
 *   apiUrl: '/api',
 *   customUpdateFn: async (id, values) => {
 *     await myApi.updateAudit(id, values);
 *   },
 * });
 */
export function useBatchUpdate({
  resourceName,
  apiUrl,
  requestHeaders,
  onComplete,
  onSuccess,
  onError,
  t = (key, defaultValue) => defaultValue || key,
  showNotification = true,
  customNotification,
  customUpdateFn,
}: UseBatchUpdateConfig): UseBatchUpdateResult {
  const [updateManyIsLoading, setUpdateManyIsLoading] = useState(false);

  const updateOne = useCallback(
    async (id: number, values: any): Promise<void> => {
      if (customUpdateFn) {
        return customUpdateFn(id, values);
      }

      const url = `${apiUrl}/${resourceName}/updateUnique/${id}`;
      const response = await fetch(url, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json;charset=utf-8',
          Accept: 'application/json',
          ...(requestHeaders?.() || {}),
        },
        body: JSON.stringify(values),
      });

      if (!response.ok) {
        throw new Error(`Update failed for id ${id}`);
      }
    },
    [apiUrl, resourceName, requestHeaders, customUpdateFn],
  );

  const updateSelectedItems = useCallback(
    async (selectedKeys: React.Key[], values: any): Promise<React.Key[]> => {
      setUpdateManyIsLoading(true);

      const successIds: React.Key[] = [];
      const failedIds: React.Key[] = [];

      for (const id of selectedKeys) {
        try {
          await updateOne(Number(id), values);
          successIds.push(id);
        } catch {
          failedIds.push(id);
        }
      }

      setUpdateManyIsLoading(false);

      const result: BatchUpdateResult = {
        successIds,
        failedIds,
        successCount: successIds.length,
        failedCount: failedIds.length,
      };

      // Callbacks
      onComplete?.(result);
      if (result.successCount > 0) {
        onSuccess?.(result);
      }
      if (result.failedCount > 0) {
        onError?.(result);
      }

      // Notification
      if (customNotification) {
        customNotification(result);
      } else if (showNotification) {
        const message = t(
          'batch.updateResult',
          `Update success: ${result.successCount}, failed: ${result.failedCount}`,
        );

        if (result.failedCount === selectedKeys.length) {
          notification.error({ message });
        } else if (result.failedCount > 0) {
          notification.warning({ message });
        } else {
          notification.success({ message });
        }
      }

      return failedIds;
    },
    [
      updateOne,
      onComplete,
      onSuccess,
      onError,
      t,
      showNotification,
      customNotification,
    ],
  );

  return {
    updateSelectedItems,
    updateOne,
    updateManyIsLoading,
  };
}
