import React, { ReactNode, useEffect, useState } from 'react';
import jwt from 'jsonwebtoken';
import { mdiForwardburger, mdiBackburger, mdiMenu } from '@mdi/js';
import menuAside from '../menuAside';
import menuNavBar from '../menuNavBar';
import BaseIcon from '../components/BaseIcon';
import NavBar from '../components/NavBar';
import NavBarItemPlain from '../components/NavBarItemPlain';
import AsideMenu from '../components/AsideMenu';
import FooterBar from '../components/FooterBar';
import { useAppDispatch, useAppSelector } from '../stores/hooks';
import Search from '../components/Search';
import { useRouter } from 'next/router';
import { findMe, logoutUser } from '../stores/authSlice';

import { hasPermission } from '../helpers/userPermissions';

type Props = {
  children: ReactNode;

  permission?: string | string[];
};

export default function LayoutAuthenticated({
  children,

  permission,
}: Props) {
  const dispatch = useAppDispatch();
  const router = useRouter();
  const { token, currentUser } = useAppSelector((state) => state.auth);
  const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
  let localToken;
  if (typeof window !== 'undefined') {
    // Perform localStorage action
    localToken = localStorage.getItem('token');
  }

  const isTokenValid = () => {
    const token = localStorage.getItem('token');
    if (!token) {
      return false;
    }

    const date = new Date().getTime() / 1000;
    const data = jwt.decode(token) as { exp?: number } | null;
    if (!data) {
      return false;
    }

    return !!data.exp && date < data.exp;
  };

  useEffect(() => {
    if (!isTokenValid()) {
      dispatch(logoutUser());
      router.push('/login');
      return;
    }

    dispatch(findMe());
  }, [token, localToken, router.pathname, router.asPath]);

  const canRenderChildren =
    !permission || (!!currentUser && hasPermission(currentUser, permission));

  const isPermissionDenied =
    !!permission && !!currentUser && !hasPermission(currentUser, permission);

  const darkMode = useAppSelector((state) => state.style.darkMode);
  const workspaceHref = currentUser?.app_role?.name?.includes('Buyer')
    ? '/buyer-portal/'
    : '/dashboard/';

  const [isAsideMobileExpanded, setIsAsideMobileExpanded] = useState(false);
  const [isAsideLgActive, setIsAsideLgActive] = useState(false);

  useEffect(() => {
    const handleRouteChangeStart = () => {
      setIsAsideMobileExpanded(false);
      setIsAsideLgActive(false);
    };

    router.events.on('routeChangeStart', handleRouteChangeStart);

    // If the component is unmounted, unsubscribe
    // from the event with the `off` method:
    return () => {
      router.events.off('routeChangeStart', handleRouteChangeStart);
    };
  }, [router.events, dispatch]);

  const layoutAsidePadding = 'xl:pl-72';

  return (
    <div
      className={`${
        darkMode ? 'dark' : ''
      } overflow-hidden lg:overflow-visible`}
    >
      <div
        className={`${layoutAsidePadding} ${
          isAsideMobileExpanded ? 'ml-72 lg:ml-0' : ''
        } pt-16 min-h-screen w-screen transition-position lg:w-auto ${bgColor}  dark:bg-dark-800 dark:text-slate-100`}
      >
        <NavBar
          menu={menuNavBar}
          className={`${layoutAsidePadding} ${
            isAsideMobileExpanded ? 'ml-60 lg:ml-0' : ''
          }`}
        >
          <NavBarItemPlain
            display='flex lg:hidden'
            onClick={() => setIsAsideMobileExpanded(!isAsideMobileExpanded)}
          >
            <BaseIcon
              path={isAsideMobileExpanded ? mdiBackburger : mdiForwardburger}
              size='24'
            />
          </NavBarItemPlain>
          <NavBarItemPlain
            display='hidden lg:flex xl:hidden'
            onClick={() => setIsAsideLgActive(true)}
          >
            <BaseIcon path={mdiMenu} size='24' />
          </NavBarItemPlain>
          <NavBarItemPlain useMargin>
            <Search />
          </NavBarItemPlain>
        </NavBar>
        <AsideMenu
          isAsideMobileExpanded={isAsideMobileExpanded}
          isAsideLgActive={isAsideLgActive}
          menu={menuAside}
          onAsideLgClose={() => setIsAsideLgActive(false)}
        />
        <main className='min-h-[calc(100vh-4rem)]'>
          {isPermissionDenied && (
            <section className='p-6'>
              <div className='mx-auto max-w-3xl rounded-2xl border border-slate-200 bg-white p-8 shadow-sm'>
                <p className='text-xs font-semibold uppercase tracking-[0.2em] text-emerald-700'>
                  Workspace access
                </p>
                <h1 className='mt-3 text-3xl font-semibold text-slate-950'>
                  This page is not available for your role.
                </h1>
                <p className='mt-3 text-sm leading-6 text-slate-500'>
                  Your account is active, but this admin module requires a
                  different permission set. Use the workspace navigation to
                  continue with the tools assigned to your role.
                </p>
                <a
                  className='mt-6 inline-flex rounded-xl bg-slate-950 px-4 py-2 text-sm font-semibold text-white hover:bg-slate-800'
                  href={workspaceHref}
                >
                  Back to workspace
                </a>
              </div>
            </section>
          )}
          {canRenderChildren && children}
        </main>
        <FooterBar>Northstar Foodservice supplier operations</FooterBar>
      </div>
    </div>
  );
}
