import { useContext, useMemo } from 'react';

import type { ToastContextValue, ToastOptions, ToastType } from '../types/toast';

import { ToastContext } from '../contexts/Toast/ToastContext';

type TypedToastOptions = Omit<ToastOptions, 'title' | 'type'>;

interface UseToastReturn extends ToastContextValue {
  info: (title: string, options?: TypedToastOptions) => string;
  success: (title: string, options?: TypedToastOptions) => string;
  warning: (title: string, options?: TypedToastOptions) => string;
  error: (title: string, options?: TypedToastOptions) => string;
  loading: (title: string, options?: TypedToastOptions) => string;
}

function createTypedToast(
  showToast: ToastContextValue['showToast'],
  type: ToastType,
): (title: string, options?: TypedToastOptions) => string {
  return (title: string, options?: TypedToastOptions): string =>
    showToast({
      ...options,
      title,
      type,
    });
}

export function useToast(): UseToastReturn {
  const context = useContext(ToastContext);

  if (!context) {
    throw new Error('useToast must be used within a ToastProvider');
  }

  return useMemo(
    () => ({
      ...context,
      info: createTypedToast(context.showToast, 'info'),
      success: createTypedToast(context.showToast, 'success'),
      warning: createTypedToast(context.showToast, 'warning'),
      error: createTypedToast(context.showToast, 'error'),
      loading: createTypedToast(context.showToast, 'loading'),
    }),
    [context],
  );
}
