import React, { useEffect, useState, useRef, useCallback } from 'react';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import { ThemeProvider } from '@mui/material/styles';

import { backstoryTheme } from '../BackstoryTheme';

import { SeverityType } from '../Components/Snack';
import { Query } from '../Components/ChatQuery';
import { ConversationHandle } from './Components/Conversation';
import { UserProvider } from './Components/UserContext';
import { BetaPage } from './Pages/BetaPage';
import { UserRoute } from './routes/UserRoute';
import { BackstoryLayout } from './Components/BackstoryLayout';

import './BackstoryApp.css';
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

import { connectionBase } from '../Global';

// Cookie handling functions
const getCookie = (name: string) => {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop()?.split(';').shift();
    return null;
};

const setCookie = (name: string, value: string, days = 7) => {
    const expires = new Date(Date.now() + days * 864e5).toUTCString();
    document.cookie = `${name}=${value}; expires=${expires}; path=/; SameSite=Strict`;
};

const BackstoryApp = () => {
    const navigate = useNavigate();
    const location = useLocation();
    const snackRef = useRef<any>(null);
    const chatRef = useRef<ConversationHandle>(null);
    const [sessionId, setSessionId] = useState<string | undefined>(undefined);
    const setSnack = useCallback((message: string, severity?: SeverityType) => {
        snackRef.current?.setSnack(message, severity);
    }, [snackRef]);
    const submitQuery = (query: Query) => {
        console.log(`handleSubmitChatQuery:`, query, chatRef.current ? ' sending' : 'no handler');
        chatRef.current?.submitQuery(query);
        navigate('/chat');
    };
    const [page, setPage] = useState<string>("");
    const [storeInCookie, setStoreInCookie] = useState(true);

    // Extract session ID from URL query parameter or cookie
    const urlParams = new URLSearchParams(window.location.search);
    const urlSessionId = urlParams.get('id');
    const cookieSessionId = getCookie('session_id');

    // Fetch or join session on mount
    useEffect(() => {
        const fetchSession = async () => {
            try {
                let response;
                let newSessionId;
                let action = ""
                if (urlSessionId) {
                    // Attempt to join session from URL
                    response = await fetch(`${connectionBase}/api/join-session/${urlSessionId}`, {
                        credentials: 'include',
                    });
                    if (!response.ok) {
                        throw new Error('Session not found');
                    }
                    newSessionId = (await response.json()).id;
                    action = "Joined";
                } else if (cookieSessionId) {
                    // Attempt to join session from cookie
                    response = await fetch(`${connectionBase}/api/join-session/${cookieSessionId}`, {
                        credentials: 'include',
                    });
                    if (!response.ok) {
                        // Cookie session invalid, create new session
                        response = await fetch(`${connectionBase}/api/create-session`, {
                            method: 'POST',
                            credentials: 'include',
                        });
                        if (!response.ok) {
                            throw new Error('Failed to create session');
                        }
                        action = "Created new";
                    } else {
                        action = "Joined";
                    }
                    newSessionId = (await response.json()).id;
                } else {
                    // Create a new session
                    response = await fetch(`${connectionBase}/api/create-session`, {
                        method: 'POST',
                        credentials: 'include',
                    });
                    if (!response.ok) {
                        throw new Error('Failed to create session');
                    }
                    action = "Created new";
                    newSessionId = (await response.json()).id;
                }
                setSessionId(newSessionId);
                setSnack(`${action} session ${newSessionId}`);

                // Store in cookie if user opts in
                if (storeInCookie) {
                    setCookie('session_id', newSessionId);
                }
                // Update URL without reloading
                if (!storeInCookie) {
                    // Update only the 'id' query parameter, preserving the current path
                    navigate(`${location.pathname}?id=${newSessionId}`, { replace: true });
                } else {
                    // Clear all query parameters, preserve the current path
                    navigate(location.pathname, { replace: true });
                }
            } catch (err) {
                setSnack("" + err);
            }
        };
        fetchSession();
    }, [cookieSessionId, setSnack, storeInCookie, urlSessionId]);

    useEffect(() => {
        const currentRoute = location.pathname.split("/")[1] ? `/${location.pathname.split("/")[1]}` : "/";
        setPage(currentRoute);
    }, [location.pathname]);

    // Render appropriate routes based on user type
    return (
        <ThemeProvider theme={backstoryTheme}>
            <UserProvider sessionId={sessionId} setSnack={setSnack}>
                <Routes>
                    <Route path="/u/:username" element={<UserRoute sessionId={sessionId} setSnack={setSnack} />} />
                    {/* Static/shared routes */}
                    <Route
                        path="/*"
                        element={
                            <BackstoryLayout
                                sessionId={sessionId}
                                setSnack={setSnack}
                                page={page}
                                chatRef={chatRef}
                                snackRef={snackRef}
                                submitQuery={submitQuery}
                            />
                        }
                    />
                </Routes>
            </UserProvider>

        </ThemeProvider>
    );
  
};

export {
  BackstoryApp
};