import { useCallback } from 'react';

import { Toast } from '../../../../components/Toast/Toast';
import { ToastAction } from '../../../../components/Toast/components/ToastAction';
import { ToastAppearance } from '../../../../components/Toast/constants';
import { WithToastIdProps } from '../types';

import { useToastManager } from './useToastManager';

/** Options that allow to configure how to show toast */
export interface ShowToastOptions {
  /** Visual toast appearance */
  appearance?: ToastAppearance;
  /** Optional action button */
  action?: {
    /** Label of action button */
    label: string;
    /** Function that will be invoked when user clicks by the action button */
    onClick?: () => void;
  };
}

/** Result of {@link useToast} hook */
export type UseToastResult = (message: string, options?: ShowToastOptions) => void;

/**
 * Hook that return function that allow to show given message as toast.
 *
 * ```tsx
 * import { useToast, ToastAppearance } from 'ui-kit';
 *
 * // Somewhere in the Component
 * const showToast = useToast();
 *
 * showToast('You\'ve wan $100 000 000', {
 *  appearance: ToastAppearance.Success,
 *  action: {
 *    label: 'Send me to PayPal',
 *    onClick: () => {},
 *  },
 * });
 * ```
 */
export function useToast(): UseToastResult {
  const { showToast } = useToastManager();

  return useCallback(
    (message: string, options?: ShowToastOptions) => {
      const duration = Math.max(Math.min(message.length * 100, 10000), 4000);

      const ToastComponent = (props: WithToastIdProps) => {
        const { hideToast } = useToastManager();

        const handleDismiss = useCallback(() => {
          hideToast(props.toastId);
        }, [hideToast, props.toastId]);

        return (
          <Toast appearance={options?.appearance} onDismiss={handleDismiss}>
            {message}
            {options?.action && (
              <ToastAction onClick={options.action.onClick}>{options.action.label}</ToastAction>
            )}
          </Toast>
        );
      };

      showToast(ToastComponent, { duration });
    },
    [showToast],
  );
}
