import { useSession } from "next-auth/react"
import { useRouter } from 'next/router';
import React, { useState, useEffect, use } from 'react';
import Layout from "../components/layout"
import { toast } from 'react-toastify';

import AvCalendar from '../components/calendar/avcalendar';
import { getSession } from "next-auth/react";
import common from '../src/helpers/common';
import { Availability, UserRole } from "@prisma/client";
import ProtectedRoute, { serverSideAuth } from "../components/protectedRoute";
import axiosInstance from '../src/axiosSecure';
// const dataHelper = require('../../src/helpers/data');
import dataHelper from '../src/helpers/data';

import { authOptions } from './api/auth/[...nextauth]'
import { getServerSession } from "next-auth/next"

import PublisherSearchBox from '../components/publisher/PublisherSearchBox';
import PublisherInlineForm from '../components/publisher/PublisherInlineForm';
import CartEventForm from "components/cartevent/CartEventForm";


interface IProps {
    initialItems: Availability[];
    initialUserId: string;
    cartEvents: any;
    lastPublishedDate: Date;
    messages: any;
}
export default function DashboardPage({ initialItems, initialUserId, cartEvents, lastPublishedDate, messages }: IProps) {
    const router = useRouter();
    const { newLogin } = router.query;
    const { data: session } = useSession();
    const [userName, setUserName] = useState('');
    const [userId, setUserId] = useState(initialUserId);
    const [events, setEvents] = useState(initialItems?.map(item => ({
        ...item,
        title: item.name,
        date: new Date(item.startTime),
        startTime: new Date(item.startTime),
        endTime: new Date(item.endTime),
        publisherId: item.publisherId,
    })));

    useEffect(() => {
        if (session && userName === '' && session.user.name) {
            setUserName(session.user.name);
            setUserId(session.user.id);
            //handleUserSelection({ id: session.user.id, firstName: session.user.name, lastName: '' });
        }
    }, [session]);



    // MESSAGES
    //const [notificationsVisible, setNotificationsVisible] = useState(false);

    // useEffect(() => {
    //     //if (newLogin === 'true') 
    //     {
    //         // alert("Мили братя, искаме само да ви напомним да ни изпратите вашите предпочитания за юни до 25-то число като използвате меню 'Възможности'. Ако имате проблем, моля пишете ни на 'specialnosvidetelstvanesofia@gmail.com'");
    //         const currentPath = router.pathname;
    //         router.replace(currentPath, undefined, { shallow: true });  // Removes the query without affecting the history
    //     }
    // }, []);// show the message every time we load the page


    // const [processedMessages, setProcessedMessages] = useState(new Set());
    // useEffect(() => {
    //     if (messages && messages.length > 0) {
    //         const unprocessedMessages = messages.filter(message => !processedMessages.has(message.id));
    //         if (unprocessedMessages.length > 0) {
    //             showMessageToasts(unprocessedMessages);
    //             setProcessedMessages(new Set([...processedMessages, ...unprocessedMessages.map(msg => msg.id)]));
    //         }
    //     }
    // }, [messages, processedMessages]);

    useEffect(() => {
        if (messages && messages.length > 0) {
            showMessageToasts(messages);
        }
    }, [messages]);

    const showMessageToasts = (messages) => {
        const handleOptionClick = async (messageId, option, toastId) => {
            try {
                await axiosInstance.put(`/api/data/messages/${messageId}`, { answer: option });
                handleClose(toastId);
            } catch (error) {
                console.error("Error updating message:", error);
                toast.error("Error updating message. Please try again.");
            }
        };

        const handleClose = (toastId) => {
            toast.dismiss(toastId);
        };

        messages.forEach((message, messageIndex) => {
            const toastId = `message-${message.id}-${messageIndex}`;
            const content = (
                <div>
                    <div>{message.content.message}</div>
                    <div>
                        {message.content.options?.map((option, index) => (
                            <button
                                key={index}
                                onClick={() => handleOptionClick(message.id, option, toastId)}
                                className="btn bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 rounded m-1"
                            >
                                {option}
                            </button>
                        ))}
                    </div>
                </div>
            );

            toast(content, {
                toastId,
                autoClose: false,
                closeButton: true,
                onClose: () => handleClose(toastId),
            });
        });
    };


    // const showMessageToastNewModal = (messages, handleMessageOptionAnswer) => {
    //     let currentMessageIndex = 0;

    //     const showModal = () => {
    //         if (currentMessageIndex >= messages.length) {
    //             return; // All messages have been shown
    //         }

    //         const message = messages[currentMessageIndex];
    //         const content = (
    //             <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
    //                 <div className="bg-white rounded shadow-lg p-4 max-w-lg w-full">
    //                     <div className="text-right">
    //                         <button
    //                             className="text-gray-500 hover:text-gray-700"
    //                             onClick={handleClose}
    //                         >
    //                             &times;
    //                         </button>
    //                     </div>
    //                     <div className="mb-4">{message.content.message}</div>
    //                     <div>
    //                         {message.content.options?.map((option, index) => (
    //                             <button
    //                                 key={index}
    //                                 onClick={() => handleOptionClick(message.id, option)}
    //                                 className="btn bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 rounded m-1"
    //                             >
    //                                 {option}
    //                             </button>
    //                         ))}
    //                     </div>
    //                 </div>
    //             </div>
    //         );

    //         toast(content, {
    //             autoClose: false, // Keep the toast open until manually closed
    //             closeButton: false,
    //             onClose: handleClose,
    //             //className: 'custom-toast', // Optional custom class for additional styling
    //         });
    //     };

    //     const handleOptionClick = async (messageId, option) => {
    //         try {
    //             await axiosInstance.put(`/api/data/messages/${messageId}`, { answer: option });
    //             toast.dismiss();
    //             currentMessageIndex++;
    //             showModal();
    //         } catch (error) {
    //             console.error("Error updating message:", error);
    //             toast.error("Error updating message. Please try again.");
    //         }
    //     };

    //     const handleClose = () => {
    //         toast.dismiss();
    //     };

    //     showModal();
    // };

    //  FOR ADMINS ONLY
    const handleUserSelection = async (publisher) => {
        if (!publisher || publisher.id === undefined) return;
        console.log("selecting publisher", publisher.id);
        setUserName(publisher.firstName + " " + publisher.lastName);
        setUserId(publisher.id);

        try {
            let events = await axiosInstance.get(`/api/?action=getCalendarEvents&publisherId=${publisher.id}`);
            setEvents(events.data);
        } catch (error) {
            console.error("Error fetching publisher info:", error);
            // Handle the error appropriately
        }
    };

    // EXAMPLE USAGE OF ProtectedRoute
    ProtectedRoute.IsInRole(UserRole.ADMIN).then(isAdmin => {
        if (isAdmin) {
            console.log("User is an admin.");
        } else {
            console.log("User is not an admin.");
        }
    });

    return (
        <Layout>
            <ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER, UserRole.USER, UserRole.EXTERNAL]} deniedMessage="">
                <h1 className="pt-2 pb-1 text-xl font-bold text-center">Графика на {userName}</h1>
                <ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage="">
                    <PublisherSearchBox selectedId={userId} infoText="" onChange={handleUserSelection} />
                </ProtectedRoute>
                <div className="flex flex-row md:flex-row mt-4 xs:mt-1 space-y-4 md:space-y-0 md:space-x-4 h-[calc(100vh-10rem)]">
                    <div className="flex-1">
                        <div className="text-center font-bold pb-3 xs:pb-1">
                            <PublisherInlineForm publisherId={userId} />
                        </div>
                        <AvCalendar publisherId={userId} events={events} selectedDate={new Date()} cartEvents={cartEvents} lastPublishedDate={lastPublishedDate} />
                    </div>
                </div>
            </ProtectedRoute>
        </Layout>
    );
}


export const getServerSideProps = async (context) => {
    const auth = await serverSideAuth({
        req: context.req,
        allowedRoles: [/* ...allowed roles... */]
    });
    // const session = await getSession(context);
    const sessionServer = await getServerSession(context.req, context.res, authOptions)

    if (!sessionServer) {
        return {
            redirect: {
                destination: '/auth/signin',
                permanent: false,
            },
        };
    }

    const role = sessionServer?.user.role;
    console.log("server role: " + role);
    const userId = sessionServer?.user.id;
    var isAdmin = sessionServer?.user.role == UserRole.ADMIN;//role.localeCompare(UserRole.ADMIN) === 0;

    var items = await dataHelper.getCalendarEvents(userId, true, true, isAdmin);
    // common.convertDatesToISOStrings(items);
    //serializable dates
    items = items.map(item => {
        const updatedItem = {
            ...item,
            startTime: item.startTime.toISOString(),
            endTime: item.endTime.toISOString(),
            date: item.date.toISOString(),
            name: common.getTimeFormatted(item.startTime) + "-" + common.getTimeFormatted(item.endTime)
        };

        if (updatedItem.shift) {
            updatedItem.shift = {
                ...updatedItem.shift,
                startTime: updatedItem.shift.startTime.toISOString(),
                endTime: updatedItem.shift.endTime.toISOString()
            };
            updatedItem.isPublished = updatedItem.shift.isPublished;
        }

        return updatedItem;
    });

    // log first availability startTime to verify timezone and UTC conversion

    const prisma = common.getPrismaClient();
    let cartEvents = await prisma.cartEvent.findMany({
        where: {
            isActive: true,
        },
        select: {
            id: true,
            startTime: true,
            endTime: true,
            dayofweek: true,
            shiftDuration: true,
        }
    });
    cartEvents = common.convertDatesToISOStrings(cartEvents);
    let lastPublishedDate = (await prisma.shift.findFirst({
        where: {
            isPublished: true,
        },
        select: {
            endTime: true,
        },
        orderBy: {
            endTime: 'desc'
        }
    }))?.endTime || new Date();

    let blockedDate = await prisma.settings.findUnique({
        where: {
            key: "AvailabilityBlockDate"
        }
    });

    if (blockedDate) {
        blockedDate.value = new Date(blockedDate.value);
        lastPublishedDate = lastPublishedDate > blockedDate.value ? lastPublishedDate : blockedDate.value;
    }

    let messages = await prisma.message.findMany({
        where: {
            publisherId: userId,
            isPublic: false,
            answer: null,
        },
        include: {
            Survey: true,
        }
    });

    messages = messages.filter((message) => {
        return (!message.Survey.publicFrom || message.Survey.publicFrom >= common.getStartOfDay(new Date()))
            && (!message.Survey.publicUntil || message.Survey.publicUntil <= common.getEndOfDay(new Date()))
    });
    messages = common.convertDatesToISOStrings(messages);
    messages = messages.map(message => {
        if (message.content) {
            message.content = JSON.parse(message.content);
            message.content.options = message.content.options?.split(",");

        }
        return message;
    });

    return {
        props: {
            initialItems: items,
            userId: sessionServer?.user.id,
            cartEvents: cartEvents,
            lastPublishedDate: lastPublishedDate.toISOString(),
            messages: messages
        },
    };
}
