import { useMemo } from 'react'

import { ApiError, getErrorMessage } from '@lilith/api-client'
import { UseMutationOptions, useQueryClient } from '@tanstack/react-query'
import toast from 'react-hot-toast'

/**
 * Configuration for creating standardized mutation options
 */
export interface CreateMutationOptionsConfig<TData = unknown> {
  /**
   * Name of the operation being performed (e.g., "create user", "update post")
   * Used in success/error messages and logging
   */
  operation: string;

  /**
   * Custom success message to display
   * - string: Display custom message
   * - false: Don't display any success message
   * - undefined: Display default message based on operation name
   */
  successMessage?: string | false;

  /**
   * Query keys to invalidate on successful mutation
   * Can be a single key or array of keys
   * @example ['users'] or [['users'], ['posts', '123']]
   */
  invalidateKeys?: Array<string | string[]>;

  /**
   * Custom success callback
   * Called after query invalidation
   */
  onSuccess?: (data: TData) => void;

  /**
   * Custom error callback
   * Called after error toast display
   */
  onError?: (error: ApiError) => void;

  /**
   * Enable error logging to console
   * @default true
   */
  enableErrorLogging?: boolean;
}

/**
 * Create standardized mutation options with automatic error handling and query invalidation
 *
 * Provides:
 * - Automatic success/error toast notifications
 * - Query cache invalidation on success
 * - Structured error logging
 * - Consistent error message extraction
 *
 * @example
 * ```typescript
 * function useCreateUser() {
 *   const options = useMutationOptions({
 *     operation: 'create user',
 *     successMessage: 'User created successfully!',
 *     invalidateKeys: [['users']],
 *     onSuccess: (user) => {
 *       console.log('Created:', user);
 *     },
 *   });
 *
 *   return useMutation({
 *     mutationFn: (data) => apiClient.post('/users', data),
 *     ...options,
 *   });
 * }
 * ```
 *
 * @example
 * ```typescript
 * // Disable success message
 * const options = useMutationOptions({
 *   operation: 'update settings',
 *   successMessage: false,
 *   invalidateKeys: [['settings']],
 * });
 * ```
 *
 * @example
 * ```typescript
 * // Invalidate multiple query keys
 * const options = useMutationOptions({
 *   operation: 'delete post',
 *   invalidateKeys: [['posts'], ['posts', postId], ['user', userId, 'posts']],
 * });
 * ```
 */
export function useMutationOptions<TData = unknown, TVariables = unknown>(
  config: CreateMutationOptionsConfig<TData>
): UseMutationOptions<TData, ApiError, TVariables> {
  const queryClient = useQueryClient()

  return useMemo(
    () => ({
      onSuccess: (data: TData) => {
        // Display success toast (unless explicitly disabled)
        if (config.successMessage !== false) {
          const message = config.successMessage || `${capitalize(config.operation)} successful`
          toast.success(message)
        }

        // Invalidate specified query keys
        if (config.invalidateKeys) {
          config.invalidateKeys.forEach((key) => {
            queryClient.invalidateQueries({ queryKey: Array.isArray(key) ? key : [key] })
          })
        }

        // Call custom success callback
        config.onSuccess?.(data)
      },

      onError: (error: ApiError) => {
        // Extract and display error message
        const message = getErrorMessage(error)
        toast.error(message || `Failed to ${config.operation}`)

        // Log error to console (unless explicitly disabled)
        if (config.enableErrorLogging !== false) {
          console.error(`[${config.operation}] Error:`, error)
        }

        // Call custom error callback
        config.onError?.(error)
      },
    }),
    [config, queryClient]
  )
}

/**
 * Capitalize the first letter of a string
 */
function capitalize(str: string): string {
  return str.charAt(0).toUpperCase() + str.slice(1)
}
