// src/components/NotificationToastHandler.tsx

/**
 * Global notification toast handler
 * Listens for WebSocket notifications and displays them as toasts
 * Should be rendered once at the app root level
 */

import { useCallback, useEffect } from 'react';
import { useWebSocket } from '../hooks/useWebSocket';
import { useEventBus } from '../hooks/useEventBus';
import toast from 'react-hot-toast';
import type { DealNotificationData, SystemMessageData } from '../types/websocket';
import { formatCurrency } from '../utils/formatUtils';

interface NotificationToastHandlerProps {
  /**
   * Whether to enable toast notifications
   * @default true
   */
  enabled?: boolean;

  /**
   * Whether to play a sound when notifications arrive
   * @default false
   */
  playSound?: boolean;

  /**
   * Custom sound URL (if playSound is true)
   */
  soundUrl?: string;
}

export function NotificationToastHandler({
  enabled = true,
  playSound = false,
  soundUrl = '/notification-sound.mp3',
}: NotificationToastHandlerProps) {
  // Connect to WebSocket
  const { isConnected, error } = useWebSocket({
    autoConnect: true,
    onConnect: () => {
      if (enabled) {
        toast.success('Connected to live notifications', {
          duration: 2000,
          icon: '🟢',
        });
      }
    },
    onDisconnect: () => {
      if (enabled && error) {
        toast.error('Disconnected from live notifications', {
          duration: 3000,
          icon: '🔴',
        });
      }
    },
  });

  // Play notification sound
  const playNotificationSound = useCallback(() => {
    if (!playSound) return;

    try {
      const audio = new Audio(soundUrl);
      audio.volume = 0.3;
      audio.play().catch((error) => {
        console.warn('Failed to play notification sound:', error);
      });
    } catch (error) {
      console.warn('Failed to play notification sound:', error);
    }
  }, [playSound, soundUrl]);

  // Handle deal notifications
  const handleDealNotification = useCallback(
    (data?: DealNotificationData) => {
      if (!enabled || !data) return;

      playNotificationSound();

      const dealsCount = data.deals.length;
      const firstDeal = data.deals[0];

      // Show toast with deal information
      toast.success(
        <div className="flex flex-col gap-1">
          <div className="font-semibold">
            {dealsCount === 1 ? 'New Deal Found!' : `${dealsCount} New Deals Found!`}
          </div>
          {dealsCount === 1 && firstDeal && (
            <div className="text-sm text-gray-600 dark:text-gray-400">
              {firstDeal.item_name} for {formatCurrency(firstDeal.best_price_in_cents)} at{' '}
              {firstDeal.store_name}
            </div>
          )}
          {dealsCount > 1 && (
            <div className="text-sm text-gray-600 dark:text-gray-400">
              Check your deals page to see all offers
            </div>
          )}
        </div>,
        {
          duration: 5000,
          icon: '🎉',
          position: 'top-right',
        },
      );
    },
    [enabled, playNotificationSound],
  );

  // Handle system messages
  const handleSystemMessage = useCallback(
    (data?: SystemMessageData) => {
      if (!enabled || !data) return;

      const toastOptions = {
        duration: data.severity === 'error' ? 6000 : 4000,
        position: 'top-center' as const,
      };

      switch (data.severity) {
        case 'error':
          toast.error(data.message, { ...toastOptions, icon: '❌' });
          break;
        case 'warning':
          toast(data.message, { ...toastOptions, icon: '⚠️' });
          break;
        case 'info':
        default:
          toast(data.message, { ...toastOptions, icon: 'ℹ️' });
          break;
      }
    },
    [enabled],
  );

  // Handle errors
  const handleError = useCallback(
    (data?: { message: string; code?: string }) => {
      if (!enabled || !data) return;

      toast.error(`Error: ${data.message}`, {
        duration: 5000,
        icon: '🚨',
      });
    },
    [enabled],
  );

  // Subscribe to event bus
  useEventBus('notification:deal', handleDealNotification);
  useEventBus('notification:system', handleSystemMessage);
  useEventBus('notification:error', handleError);

  // Show connection error if persistent
  useEffect(() => {
    if (error && !isConnected) {
      // Only show after a delay to avoid showing on initial connection
      const timer = setTimeout(() => {
        if (error && !isConnected && enabled) {
          toast.error('Unable to connect to live notifications. Some features may be limited.', {
            duration: 5000,
            icon: '⚠️',
          });
        }
      }, 5000);

      return () => clearTimeout(timer);
    }
  }, [error, isConnected, enabled]);

  // This component doesn't render anything - it just handles side effects
  return null;
}
