/**
 * Toast hook for managing toast notifications
 */

import { useState, useCallback, useEffect } from 'react';

export type ToastType = 'success' | 'error' | 'warning' | 'info';
export type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';

export interface Toast {
  id: string;
  type: ToastType;
  title?: string;
  message: string;
  duration?: number;
  dismissible?: boolean;
  action?: {
    label: string;
    onClick: () => void;
  };
  timestamp: number;
}

interface ToastState {
  toasts: Toast[];
  position: ToastPosition;
  maxToasts: number;
}

interface ToastOptions {
  type?: ToastType;
  title?: string;
  duration?: number;
  dismissible?: boolean;
  action?: {
    label: string;
    onClick: () => void;
  };
}

interface ToastActions {
  addToast: (message: string, options?: ToastOptions) => string;
  removeToast: (id: string) => void;
  clearToasts: () => void;
  success: (message: string, options?: Omit<ToastOptions, 'type'>) => string;
  error: (message: string, options?: Omit<ToastOptions, 'type'>) => string;
  warning: (message: string, options?: Omit<ToastOptions, 'type'>) => string;
  info: (message: string, options?: Omit<ToastOptions, 'type'>) => string;
  setPosition: (position: ToastPosition) => void;
  setMaxToasts: (max: number) => void;
}

const DEFAULT_DURATION = 5000; // 5 seconds
const DEFAULT_POSITION: ToastPosition = 'top-right';
const DEFAULT_MAX_TOASTS = 6;

// Generate unique ID
const generateId = (): string => {
  return `toast_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
};

export const useToast = (
  initialPosition: ToastPosition = DEFAULT_POSITION,
  initialMaxToasts: number = DEFAULT_MAX_TOASTS
): ToastState & ToastActions => {
  const [state, setState] = useState<ToastState>({
    toasts: [],
    position: initialPosition,
    maxToasts: initialMaxToasts,
  });

  // Remove toast by ID
  const removeToast = useCallback((id: string) => {
    setState(prev => ({
      ...prev,
      toasts: prev.toasts.filter(toast => toast.id !== id),
    }));
  }, []);

  // Add toast
  const addToast = useCallback((message: string, options: ToastOptions = {}): string => {
    const id = generateId();
    
    const toast: Toast = {
      id,
      type: options.type || 'info',
      title: options.title,
      message,
      duration: options.duration ?? DEFAULT_DURATION,
      dismissible: options.dismissible ?? true,
      action: options.action,
      timestamp: Date.now(),
    };

    setState(prev => {
      const newToasts = [...prev.toasts, toast];
      
      // Limit number of toasts
      if (newToasts.length > prev.maxToasts) {
        return {
          ...prev,
          toasts: newToasts.slice(-prev.maxToasts),
        };
      }
      
      return {
        ...prev,
        toasts: newToasts,
      };
    });

    // Auto-dismiss toast if duration is set
    if (toast.duration && toast.duration > 0) {
      setTimeout(() => {
        removeToast(id);
      }, toast.duration);
    }

    return id;
  }, [removeToast]);

  // Clear all toasts
  const clearToasts = useCallback(() => {
    setState(prev => ({
      ...prev,
      toasts: [],
    }));
  }, []);

  // Convenience methods for different toast types
  const success = useCallback((message: string, options: Omit<ToastOptions, 'type'> = {}) => {
    return addToast(message, { ...options, type: 'success' });
  }, [addToast]);

  const error = useCallback((message: string, options: Omit<ToastOptions, 'type'> = {}) => {
    return addToast(message, { ...options, type: 'error', duration: options.duration ?? 8000 });
  }, [addToast]);

  const warning = useCallback((message: string, options: Omit<ToastOptions, 'type'> = {}) => {
    return addToast(message, { ...options, type: 'warning' });
  }, [addToast]);

  const info = useCallback((message: string, options: Omit<ToastOptions, 'type'> = {}) => {
    return addToast(message, { ...options, type: 'info' });
  }, [addToast]);

  // Set toast position
  const setPosition = useCallback((position: ToastPosition) => {
    setState(prev => ({
      ...prev,
      position,
    }));
  }, []);

  // Set maximum number of toasts
  const setMaxToasts = useCallback((maxToasts: number) => {
    setState(prev => {
      const newToasts = prev.toasts.length > maxToasts 
        ? prev.toasts.slice(-maxToasts)
        : prev.toasts;
        
      return {
        ...prev,
        maxToasts,
        toasts: newToasts,
      };
    });
  }, []);

  return {
    ...state,
    addToast,
    removeToast,
    clearToasts,
    success,
    error,
    warning,
    info,
    setPosition,
    setMaxToasts,
  };
};