import React, { useEffect, useState } from 'react';
import common from '../src/helpers/common'; // Ensure this path is correct
//use session to get user role
import { useSession } from "next-auth/react"
import e from 'express';
import ProtectedRoute from './protectedRoute';
import { UserRole } from '@prisma/client';

function PwaManager({ userId, subs }) {
    //ToDo: for iOS, try to use apn? https://github.com/node-apn/node-apn/blob/master/doc/apn.markdown
    const isSupported = () =>
        'Notification' in window &&
        'serviceWorker' in navigator &&
        'PushManager' in window

    const [inProgress, setInProgress] = useState(false)
    const [deferredPrompt, setDeferredPrompt] = useState(null);
    const [isPWAInstalled, setIsPWAInstalled] = useState(false);
    const [isStandAlone, setIsStandAlone] = useState(false);
    const [isSubscribed, setIsSubscribed] = useState(false);
    const [subscription, setSubscription] = useState(null);
    const [registration, setRegistration] = useState(null);
    const [notificationPermission, setNotificationPermission] = useState(isSupported() && Notification.permission);
    const [_subs, setSubs] = useState(subs)

    const { data: session } = useSession();
    // let isAdmin = ProtectedRoute.IsInRole(UserRole.ADMIN);
    let isAdmin = false;
    if (session) {
        isAdmin = session.user.role === UserRole.ADMIN;
    }


    // Handle PWA installation
    useEffect(() => {
        if (isSupported()) {
            setNotificationPermission(Notification.permission);
            getSubscriptionCount();
        }

        // Handle Push Notification Subscription
        if ('serviceWorker' in navigator && 'PushManager' in window) {
            navigator.serviceWorker.ready.then(swreg => {
                swreg.pushManager.getSubscription().then(sub => {
                    if (sub) {
                        setSubscription(sub);
                        setIsSubscribed(true);
                    }
                });
                setRegistration(swreg);
            });
        }

        // Check if the app is running in standalone mode
        // const isStandalone = window.matchMedia('(display-mode: standalone)').matches;
        // if (isStandalone) {
        //     console.log('Running in standalone mode');
        //     setIsPWAInstalled(true);
        // }

        if (window.matchMedia('(display-mode: standalone)').matches) {
            setIsStandAlone(true);
        }

        const handleBeforeInstallPrompt = (e) => {
            e.preventDefault();
            setDeferredPrompt(e);
        };

        const handleAppInstalled = () => {
            setIsPWAInstalled(true);
        };

        window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
        window.addEventListener('appinstalled', handleAppInstalled);

        return () => {
            window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
            window.removeEventListener('appinstalled', handleAppInstalled);
        };




    }, []);


    const installPWA = async (e) => {
        console.log('Attempting to install PWA');
        e.preventDefault(); // Prevent default button action
        if (deferredPrompt) {
            console.log('Prompting install');
            deferredPrompt.prompt();
            const { outcome } = await deferredPrompt.userChoice;
            console.log('Installation outcome:', outcome);
            if (outcome === 'accepted') {
                console.log('User accepted the A2HS prompt');
                setIsPWAInstalled(true);
            } else {
                console.log('User dismissed the A2HS prompt');
            }
            setDeferredPrompt(null); // Clear the deferred prompt to manage its lifecycle
        } else {
            console.log('No deferred prompt available');
        }
    };


    const subscribeToNotifications = async (e) => {

        try {
            e.preventDefault();
            if (!navigator.serviceWorker) {
                console.error('Service worker is not supported by this browser.');
                return;
            }

            const registration = await navigator.serviceWorker.ready;
            if (!registration) {
                console.error('Service worker registration not found.');
                return;
            }

            let vapidPublicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;
            if (!vapidPublicKey) {
                // Fetch the public key from the server if not present in env variables
                const response = await fetch('/api/notify', { method: 'GET' });
                const responseData = await response.json();
                vapidPublicKey = responseData.pk;
                setSubs(responseData.subs);
                if (!vapidPublicKey) {
                    throw new Error("Failed to fetch VAPID public key from server.");
                }
            }

            const sub = await registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: common.base64ToUint8Array(vapidPublicKey)
            });
            // Call your API to save subscription data on server
            if (session.user?.id != null) {
                await fetch(`/api/notify`, {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ subscription: sub, id: session.user.id })
                }).then(async response => {
                    if (!response.ok) {
                        //throw new Error('Failed to save subscription data on server.');
                        console.log('Failed to save subscription data on server.');
                    }
                    else {
                        console.log('Subscription data saved on server.');
                        const s = await response.json();
                        setSubs(s.subs);
                        setSubscription(sub);
                        setIsSubscribed(true);
                        console.log('Web push subscribed!');
                    }
                });
            }
            console.log(sub);
        } catch (error) {
            console.error('Error subscribing to notifications:', error);
        }
    };

    const unsubscribeFromNotifications = async (e) => {

        try {
            e.preventDefault();
            if (subscription) {
                await subscription.unsubscribe();
                // Call your API to delete or invalidate subscription data on server
                setSubscription(null);
                setIsSubscribed(false);
                if (session?.user?.id != null) {
                    await fetch(`/api/notify`,
                        {
                            method: 'DELETE',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            //send the current subscription to be removed
                            body: JSON.stringify({ id: session.user.id, subscriptionId: subscription.endpoint })
                        }
                    ).then(async (response) => {
                        if (!response.ok) {
                            throw new Error('Failed to delete subscription data on server.');
                        }
                        else {
                            console.log('Subscription data deleted on server.');
                            const s = await response.json();
                            setSubs(s.subs);
                        }
                    });
                }
                console.log('Web push unsubscribed!');
            }
        } catch (error) {
            console.error('Error unsubscribing from notifications:', error);
        }
    };

    const getSubscriptionCount = async () => {
        try {
            const response = await fetch('/api/notify?id=' + session.user.id, { method: 'GET' });
            if (!response.ok) {
                throw new Error('Failed to fetch subscription data.');
            }
            const result = await response.json();
            setSubs(result.subs);
        } catch (error) {
            console.error('Error fetching subscription data:', error);
        }
    };

    // Function to request push notification permission
    const requestNotificationPermission = async (e) => {
        e.preventDefault();
        if (isSupported()) {
            const permission = await Notification.requestPermission();
            setNotificationPermission(permission);
            if (permission === "granted") {
                // User granted permission
                subscribeToNotifications(null); // Pass the required argument here
            } else {
                // User denied or dismissed permission
                console.log("Push notifications permission denied.");
            }
        }
        else {
            console.error('Web push not supported');
        }
    };

    // Function to toggle push notifications
    const togglePushNotifications = async (e) => {

        e.preventDefault();
        if (notificationPermission === "granted") {
            // If already subscribed, unsubscribe
            unsubscribeFromNotifications(null); // Pass null as the argument
        } else if (notificationPermission === "default" || notificationPermission === "denied") {
            // Request permission if not already granted
            await requestNotificationPermission(e);
        }
    };


    const sendTestNotification = async (e) => {

        e.preventDefault();
        if (!subscription) {
            console.error('Web push not subscribed');
            return;
        }

        await fetch('/api/notify', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(
                {
                    id: session.user.id,
                    title: "Тестово уведомление",
                    message: "Това е тестово уведомление",
                    actions: [{ action: 'test', title: 'Тест', icon: '✅' },
                    { action: 'close', title: 'Затвори', icon: '❌' }]
                })
        });

        /*
                                                                    await fetch('/api/notify', {
                                                                        method: 'POST',
                                                                        headers: {
                                                                            'Content-Type': 'application/json'
                                                                        },
                                                                        body: JSON.stringify({
                                                                            id: pub.id,
                                                                            message: "Тестово съобщение",
                                                                            title: "Това е тестово съобщение от https://sofia.mwitnessing.com",
                                                                            actions: [
                                                                                { action: 'OK', title: 'OK', icon: '✅' },
                                                                                { action: 'close', title: 'Затвори', icon: '❌' }
                                                                            ]
                                                                            // actions: [
                                                                            //     {
                                                                            //         title: 'Open URL',
                                                                            //         action: 'open_url',
                                                                            //         icon: '/images/open-url.png'
                                                                            //     },
                                                                            //     {
                                                                            //         title: 'Dismiss',
                                                                            //         action: 'dismiss',
                                                                            //         icon: '/images/dismiss.png'
                                                                            //     }
                                                                            // ]
                                                                        })
                                                                    })
                                                                    */

    };

    // async function sendTestReminder(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
    //     event.preventDefault();
    //     if (!subscription) {
    //         console.error('Web push not subscribed');
    //         return;
    //     }

    //     await fetch('/api/notify', {
    //         method: 'POST',
    //         headers: {
    //             'Content-Type': 'application/json'
    //         },
    //         body: JSON.stringify({
    //             broadcast: true,
    //             message: "Мили братя, искаме да ви напомним да ни изпратите вашите предпочитания за юни до 25-то число като използвате меню 'Възможности'. Ако имате проблем, моля пишете ни на 'specialnosvidetelstvanesofia@gmail.com'"
    //         })
    //     });
    // }

    // async function sendTestCoverMe(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
    //     event.preventDefault();
    //     if (!subscription) {
    //         console.error('Web push not subscribed');
    //         return;
    //     }

    //     await fetch('/api/notify', {
    //         method: 'POST',
    //         headers: {
    //             'Content-Type': 'application/json'
    //         },
    //         body: JSON.stringify({
    //             id: session.user.id,
    //             message: "Брат ТЕСТ търси заместник за 24-ти май от 10:00 ч. Можеш ли да го покриеш?",
    //             //use fontawesome icons for actions
    //             actions: [{ action: 'covermeaccepted', title: 'Да ', icon: '✅' }]
    //         })
    //     });
    // }

    async function deleteAllSubscriptions(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
        event.preventDefault();
        await fetch(`/api/notify`,
            {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json'
                },
                //send the current subscription to be removed
                body: JSON.stringify({ id: session.user.id })
            }
        ).then(async response => {
            if (!response.ok) {
                throw new Error('Failed to delete subscription data on server.');
            }
            else {
                console.log('ALL subscriptions data deleted on server.');
                if (subscription) {
                    await subscription.unsubscribe();
                }
                setSubs("");
                setSubscription(null);
                setIsSubscribed(false);
            }
        });
    }
    if (!isSupported()) {
        return (
            <div>
                <p>Това устройство не поддържа нотификации</p>
            </div>
        );
    }
    else {
        return (
            <>
                <div>
                    <h1>{isAdmin && " PWA (admin)"}</h1>
                    {!isStandAlone && !isPWAInstalled && (
                        <button
                            onClick={installPWA}
                            className="bg-blue-500 hover:bg-blue-700 text-white text-xs py-1 px-2 rounded-full focus:outline-none focus:shadow-outline transition duration-150 ease-in-out"
                        >
                            Инсталирай приложението
                        </button>
                    )}
                    {isPWAInstalled && <p>Инсталирано!</p>}
                    {/* {isStandAlone && <p>PWA App</p>} */}

                    <button
                        onClick={isSubscribed ? unsubscribeFromNotifications : subscribeToNotifications}
                        disabled={false} // Since the button itself acts as a toggle, the disabled attribute might not be needed
                        className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${isSubscribed ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'}`} >
                        {isSubscribed ? 'Спри известията' : 'Показвай известия'}
                    </button>
                    <button
                        onClick={deleteAllSubscriptions}
                        className="text-xs py-1 px-2 rounded-full focus:outline-none bg-red-500 hover:bg-red-700 text-white"
                    >
                        Спри известията на всички мои устройства {_subs != "" ? `(${_subs})` : ""}
                    </button>
                    <button
                        onClick={sendTestNotification}
                        disabled={!isSubscribed}
                        className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-yellow-500 hover:bg-yellow-600 text-white'
                            }`}
                    >
                        Тестово уведомление
                    </button>
                </div >
                {isAdmin &&
                    <div>
                        {/* <button
                            onClick={sendTestReminder}
                            disabled={!isSubscribed}
                            className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-yellow-500 hover:bg-yellow-600 text-white'
                                }`}
                        >
                            Broadcast Reminder
                        </button> */}
                        {/* <button
                            onClick={sendTestCoverMe}
                            disabled={!isSubscribed}
                            className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-yellow-500 hover:bg-yellow-600 text-white'
                                }`}
                        >
                            Broadcast CoverMe
                        </button> */}
                    </div>
                }
                {
                    notificationPermission !== "granted" && (
                        <button
                            onClick={togglePushNotifications}
                            className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${notificationPermission === "denied" ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'
                                }`}
                        >
                            {notificationPermission === "denied" ? 'Notifications Denied!' : 'Enable Notifications'}
                        </button>
                    )
                }

                {
                    isAdmin && <div>
                        <div>
                            <a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
                                <img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
                                <span className="align-middle">Телеграм</span>
                            </a>

                            <a href="/api/auth/apple-signin" className="inline-flex items-center ml-4 bg-gray-100 button" target="_blank">
                                <span className="align-middle">Apple sign-in</span>
                            </a>
                        </div>
                    </div>
                }
            </>
        );
    }
}
export default PwaManager;

//get server side props - subs count
export const getServerSideProps = async (context) => {
    //ToDo: get the number of subscriptions from the database
    return {
        props: {
            subs: 0
        }
    }
}
