import React, { useEffect, useState } from "react";
import NavLayout from "./NavLayout.tsx";
import { Route, Routes, useNavigate } from "react-router-dom";
import Home from "../Home.tsx";
import './MainLayout.css';
import { validateToken, GetUserPrivileges, TokenPayload, UnAuthorized } from '../Auth/Auth.tsx';
import '../LoadingScreen.css'
import AccountDropdown from "./AccountDropdown.tsx";
import AccountSettings from "../Auth/AccountSetting.tsx";
import { Api as Auth } from '../client/auth_client.ts';
import '../Pages/NotFound.tsx';
import NotFound from "../Pages/NotFound.tsx";
import "../Pages/UserAccountList.tsx";
import UserAccountList from "../Pages/UserAccountList.tsx";

const MainLayout: React.FC = () => {
    const [tokenPayload, setTokenPayload] = useState<TokenPayload | null>(null);
    const [tokenExpiryTime, setTokenExpiryTime] = useState<number | null>(null);
    const [isAuthenticating, setIsAuthenticating] = useState(true);
    const [privilegesList, setPrivilegesList] = useState<string[]>();
    const [isTokenRegenerating, setIsTokenRegenerating] = useState<boolean>(false);
    const navigate = useNavigate();

    useEffect(() => {
        const validateAndSetToken = async () => {
            if (isTokenRegenerating) return;

            const token = localStorage.getItem('authToken');
            if (token) {
                const payload = await validateToken(token);
                if (payload) {
                    setTokenPayload(payload);
                    setTokenExpiryTime(payload.exp);
                    setIsAuthenticating(false);
                } else {
                    localStorage.removeItem('authToken');
                    navigate('/login');
                }
            } else {
                navigate('/login');
            }
        };

        const getUserPrivileges = async () => {
            const privileges = await GetUserPrivileges(navigate);
            setPrivilegesList(privileges);
        };

        getUserPrivileges().then();
        validateAndSetToken().then();
    }, [navigate, isTokenRegenerating]);

    useEffect(() => {
        if (tokenExpiryTime) {
            const currentTime = Math.floor(Date.now() / 1000);
            const timeUntilExpiry = tokenExpiryTime - currentTime;

            if (timeUntilExpiry > 900) {
                const timeoutId = setTimeout(() => {
                    regenerateToken().then();
                }, (timeUntilExpiry - 900) * 1000);
                return () => clearTimeout(timeoutId);
            } else {
                regenerateToken().then();
            }
        }
    }, [tokenExpiryTime]);

    const regenerateToken = async () => {
        if (isTokenRegenerating) return;

        setIsTokenRegenerating(true);
        const token = localStorage.getItem('authToken');
        if (token) {
            const client = new Auth({
                baseUrl: 'auth',
                securityWorker: () => ({ headers: { Authorization: `Bearer ${token}` } }),
            });
            try {
                const responseToken = await client.regenerateToken.regenerateTokenList();
                if (responseToken.status === 401) {
                    await UnAuthorized(navigate);
                } else if (responseToken.data.token) {
                    const newToken = responseToken.data.token;
                    localStorage.setItem('authToken', newToken);
                    const newPayload = await validateToken(newToken);
                    if (newPayload) {
                        setTokenPayload(newPayload);
                        setTokenExpiryTime(newPayload.exp);
                    } else {
                        await validateToken(newToken);
                    }
                }
            } catch (error) {
                console.error('Token regeneration failed', error);
                localStorage.removeItem('authToken');
                navigate('/login');
            } finally {
                setIsTokenRegenerating(false);
            }
        } else {
            setIsTokenRegenerating(false);
            navigate('/login');
        }
    };

    if (isAuthenticating) {
        return (
            <div className="loading-screen">
                <div className="spinner">
                    <div className="lds-ring">
                        <div></div>
                        <div></div>
                        <div></div>
                        <div></div>
                    </div>
                </div>
            </div>
        );
    }

    return (
        <div className="page">
            <div className="sidebar">
                <NavLayout privilegeList={privilegesList} />
            </div>

            <main className="main-content">
                <div className="top-row px-4">
                    {tokenPayload && (
                        <AccountDropdown
                            tokenPayload={tokenPayload}
                            privilegeList={privilegesList}
                        />
                    )}
                </div>
                <div className="content px-4">
                    <Routes>
                        <Route path="/" element={<Home tokenPayload={tokenPayload} />} />

                        <Route
                            path="/accountSettings/"
                            element={<AccountSettings />}
                        />
                        <Route path="/accounts/" element={<UserAccountList />} />
                        <Route path="/*" element={<NotFound />} />
                    </Routes>
                </div>
            </main>
        </div>
    );
};

export default MainLayout;
