import { Menu } from '@ark-ui/react';
import { useViewportSize } from '@mantine/hooks';
import { FC, useState } from 'react';
import { NavLink, useLocation, useMatches, useNavigate } from 'react-router';

import { Group, Stack } from '../components';
import { usePreferenceStore } from '../store';
import { twx } from '../utils';

interface Scene {
  title: string;
  path: string;
  icon?: string;
  disable?: boolean;
  children?: Scene[];
}

// TODO: update path
const scenes: Scene[] = [
  {
    title: 'Home',
    path: '/',
    icon: 'i-ant-design-home-filled',
  },
  {
    title: 'Staff',
    path: '/staff-record',
    icon: 'i-bi:people-fill',
  },
  {
    title: 'Leave Application',
    path: '/leave-application-record',
    icon: 'i-mdi:tick',
  },
  {
    title: 'Leave Cancellation',
    path: '/leave-cancellation-record',
    icon: 'i-mdi:cancel-bold',
  },
  {
    title: 'Leave Transaction',
    path: '/leave-transaction-record',
    icon: 'i-ant-design:transaction-outlined',
  },
  {
    title: 'Leave Credit Application',
    path: '/leave-credit-application-record',
    icon: 'i-fluent:wallet-credit-card-24-filled',
  },
  {
    title: 'Attendance',
    path: '/attendance-record',
    icon: 'i-fluent:wallet-credit-card-24-filled',
  },
  {
    title: 'Report',
    path: '/report-record',
    icon: 'i-fluent:wallet-credit-card-24-filled',
  },
];

export const NavBar: FC = () => {
  const navCollapsed = usePreferenceStore.use.navCollapsed();
  const togglePreference = usePreferenceStore.use.togglePreference();

  return (
    <Group className="bg-red overflow-hidden">
      <div
        className={twx([
          'fixed z-50 h-full transition-all ',
          navCollapsed ? 'w-16' : 'w-60',
        ])}
      >
        <Stack className="h-full w-full flex flex-col items-stretch border-r bg-zinc-100 shadow-lg backdrop-blur-xl">
          <div className="ml-auto flex">
            <button
              className="h-13.5 w-16 flex items-center justify-center p-2 transition-colors duration-200"
              onClick={() => togglePreference('navCollapsed')}
            >
              <div
                className={twx(
                  'text-2xl text-black',
                  navCollapsed
                    ? 'i-ant-design-menu-fold-outlined rotate-180'
                    : 'i-ant-design-menu-fold-outlined',
                )}
              />
            </button>
          </div>
          <Stack className="z-1 gap-2.5">
            {scenes.map((scene) =>
              scene.children ? (
                <NavGroup key={scene.title} scene={scene} />
              ) : (
                <NavItem key={scene.title} scene={scene} />
              ),
            )}
          </Stack>
          <Stack
            className={twx(
              'mt-auto text-black/90 dark:text-white/90 transition-all fixed bottom-2 ',
              navCollapsed ? 'left--60' : 'left-0',
            )}
          ></Stack>
        </Stack>
      </div>
    </Group>
  );
};

export type NavGroupProps = {
  scene: Scene;
};

const NavGroup: FC<NavGroupProps> = ({ scene }) => {
  const { title, icon, path, children } = scene;
  const matches = useMatches();
  const isParent = matches.some(({ pathname }) => {
    return pathname.includes(path);
  });
  const [opened, setOpened] = useState(isParent);
  const navCollapsed = usePreferenceStore.use.navCollapsed();

  return (
    <Stack
      className={twx(`transition-all overflow-hidden dark:bg-zinc-800`)}
      style={{
        height: (navCollapsed ? navCollapsed : !opened)
          ? '48px'
          : `${((scene.children?.length ?? 1) + 1) * 50 + 1}px`,
      }}
    >
      <Menu.Root positioning={{ placement: 'left-start' }} closeOnSelect>
        <Menu.Trigger className="flex bg-transparent">
          <div
            className={twx([
              'bg-white dark:bg-zinc-800 items-center transition-all ease duration-200 text-sm border-l-4 text-black/90 dark:text-white/90 hover:dark:bg-zinc-900 pl-2',
              isParent
                ? navCollapsed
                  ? 'border-l-transparent dark:text-[#ffce6f] text-orange-6'
                  : 'text-orange-6  border-l-amber-600 bg-gradient-to-r from-amber-500/30 dark:text-[#ffce6f]'
                : ' border-transparent hover:bg-amber-100',
              navCollapsed ? 'w-16' : 'w-full',
            ])}
            onClick={(e) => {
              setOpened((o) => !o);
              if (!navCollapsed) {
                e.preventDefault();
              }
            }}
          >
            <Group className="gap-4 p-2.5 py-3.5">
              <div className={twx('h-5 w-5')}>
                <p className={`${icon} w-full h-full`} />
              </div>
              <Group
                className={twx(
                  'transition-all overflow-hidden justify-between',
                  navCollapsed ? 'w-0' : 'flex-1',
                )}
              >
                <p className="text-nowrap">{title}</p>
                {!navCollapsed &&
                  (!opened ? (
                    <div className="i-mdi-chevron-down ml-1 h-5 w-5" />
                  ) : (
                    <div className="i-mdi-chevron-up ml-1 h-5 w-5" />
                  ))}
              </Group>
            </Group>
          </div>
        </Menu.Trigger>
        <Menu.Positioner>
          <Menu.Content className="z-20 mt--1 border border-zinc-700 rounded bg-zinc-700 text-white">
            {children?.map((scene) => {
              return (
                <Menu.Item value="" key={scene.path}>
                  <MenuNavItem scene={scene} />
                </Menu.Item>
              );
            })}
          </Menu.Content>
        </Menu.Positioner>
      </Menu.Root>
      <Stack className="border-y-2 p-0 dark:border-zinc-700">
        {children?.map((scene) => {
          return <NavItem key={scene.path} scene={scene} isChildren />;
        })}
      </Stack>
    </Stack>
  );
};

export type NavItemProps = {
  scene: Scene;
  isChildren?: boolean;
};

const NavItem: FC<NavItemProps> = ({ scene, isChildren }) => {
  const { width } = useViewportSize();
  const { path, title, icon, disable } = scene;
  const navCollapsed = usePreferenceStore.use.navCollapsed();
  const updatePreference = usePreferenceStore.use.updatePreference();
  return (
    <NavLink
      key={path}
      to={path}
      state={{ title }}
      className={({ isActive }) =>
        twx(
          'transition-all ease duration-200 text-sm border-l-4 text-black/90 dark:text-white/90 hover:dark:bg-zinc-900 pl-2',
          isActive
            ? isChildren
              ? 'border-l-transparent dark:text-orange-2 text-orange-6'
              : navCollapsed
                ? 'border-l-transparent dark:text-orange-2 text-orange-6'
                : 'text-orange-6 border-l-orange-6 bg-gradient-to-r from-orange-5/30 dark:bg-zinc-800 dark:text-orange-2'
            : 'border-transparent hover:bg-orange-1',
          disable && 'text-black/50 dark:text-white/50 pointer-events-none',
          navCollapsed ? 'w-16' : 'w-full',
          isActive && 'isActive',
        )
      }
      onClick={(e) => {
        if (width < 1024) updatePreference({ navCollapsed: true });
        if (e.currentTarget.className.includes('isActive')) {
          e.preventDefault();
        }
      }}
    >
      <Group className="w-full gap-4 p-2.5 py-3.5">
        <div className={twx('h-5 w-5')}>
          <p className={`${icon} w-full h-full`} />
        </div>
        <div
          className={twx(
            'transition-all overflow-hidden',
            navCollapsed ? 'w-0' : 'flex-1',
          )}
        >
          <p className="text-nowrap">{title}</p>
        </div>
      </Group>
    </NavLink>
  );
};

export type MenuNavItemProps = {
  scene: Scene;
};

const MenuNavItem: FC<MenuNavItemProps> = ({ scene }) => {
  const { path, title } = scene;
  const navigate = useNavigate();
  const location = useLocation();
  const isActive = location.pathname.includes(path);
  return (
    <Group
      className={twx(
        'w-full cursor-pointer justify-center gap-4 p-2 hover:bg-[#745d35]',
        isActive && 'bg-[#81683b]',
      )}
      onClick={() => navigate(path)}
    >
      {title}
    </Group>
  );
};
