/**
 * WebSocket hook for real-time alerts
 */

import { useEffect, useRef, useState, useCallback } from 'react';
import { toast } from 'sonner';

interface AlertMessage {
    id: string;
    type: string;
    sensorName: string;
    value: number;
    threshold: number;
    message: string;
    timestamp: string;
}

interface UseNotificationsOptions {
    showToasts?: boolean;
    playSound?: boolean;
}

export function useNotifications(options: UseNotificationsOptions = {}) {
    const { showToasts = true, playSound = true } = options;
    const wsRef = useRef<WebSocket | null>(null);
    const [connected, setConnected] = useState(false);
    const [alerts, setAlerts] = useState<AlertMessage[]>([]);
    const [unreadCount, setUnreadCount] = useState(0);

    const connect = useCallback(() => {
        // Determine WebSocket URL based on current location
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const host = window.location.host;
        const wsUrl = `${protocol}//${host}/api/ws/alerts`;

        try {
            const ws = new WebSocket(wsUrl);
            wsRef.current = ws;

            ws.onopen = () => {
                console.log('🔔 Notification WebSocket connected');
                setConnected(true);
            };

            ws.onmessage = (event) => {
                try {
                    const message = JSON.parse(event.data);

                    if (message.type === 'ALERT') {
                        const alert = message.data as AlertMessage;

                        // Add to alerts list
                        setAlerts(prev => [alert, ...prev].slice(0, 50));
                        setUnreadCount(prev => prev + 1);

                        // Show toast notification
                        if (showToasts) {
                            const isHigh = alert.type.includes('HIGH');
                            toast.error(alert.message, {
                                icon: isHigh ? '🔥' : '❄️',
                                duration: 10000,
                                action: {
                                    label: 'View',
                                    onClick: () => {
                                        // Could navigate to environment dashboard
                                        window.location.href = '/environment';
                                    }
                                }
                            });
                        }

                        // Play sound
                        if (playSound) {
                            playAlertSound();
                        }
                    }
                } catch (e) {
                    console.warn('Failed to parse WebSocket message:', e);
                }
            };

            ws.onclose = () => {
                console.log('🔔 Notification WebSocket disconnected');
                setConnected(false);

                // Reconnect after delay
                setTimeout(connect, 5000);
            };

            ws.onerror = (error) => {
                console.error('WebSocket error:', error);
                ws.close();
            };
        } catch (error) {
            console.error('Failed to connect WebSocket:', error);
        }
    }, [showToasts, playSound]);

    const disconnect = useCallback(() => {
        if (wsRef.current) {
            wsRef.current.close();
            wsRef.current = null;
        }
    }, []);

    const clearUnread = useCallback(() => {
        setUnreadCount(0);
    }, []);

    const clearAll = useCallback(() => {
        setAlerts([]);
        setUnreadCount(0);
    }, []);

    useEffect(() => {
        connect();
        return () => disconnect();
    }, [connect, disconnect]);

    return {
        connected,
        alerts,
        unreadCount,
        clearUnread,
        clearAll,
    };
}

function playAlertSound() {
    try {
        // Create a simple beep sound
        const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
        if (!AudioContext) return;

        const ctx = new AudioContext();
        const oscillator = ctx.createOscillator();
        const gainNode = ctx.createGain();

        oscillator.connect(gainNode);
        gainNode.connect(ctx.destination);

        oscillator.frequency.setValueAtTime(880, ctx.currentTime); // A5
        gainNode.gain.setValueAtTime(0.3, ctx.currentTime);
        gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.3);

        oscillator.start(ctx.currentTime);
        oscillator.stop(ctx.currentTime + 0.3);
    } catch {
        // Ignore audio errors
    }
}
