import React, {
  useEffect,
  useState,
  useRef,
  useCallback,
  useMemo,
} from 'react';
import Link from 'next/link';
import { Text } from '@/components/ui/text';
import {
  Sheet,
  SheetTrigger,
  SheetContent,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet';
import CommonImage from '../common/CommonImage';
import { usePathname } from 'next/navigation';
import { globalApiPost } from '@/services/global/globalApiCalls';
import { API_ENDPOINTS } from '@/constants';
import { Switch } from '@/components/ui/switch';
import { VC_FE_URL, WOSA_ADMIN_URL, WOSA_BASE_URL } from '@/config/site-config';
import { store } from '@/store/store';
import { setMenuItems } from '@/store/slices/menuSlice';
import { useSelector } from 'react-redux';
import { createSelector } from '@reduxjs/toolkit';
import { ApiError, UnknownRecord } from '@/types';
import { hydrateSession } from '@/store/slices/sessionSlice';
import Bookmarks from './Bookmarks';
import RecentVisits from './RecentVisits';

interface VisitedPage {
  href: string;
  title: string;
  platform?: string;
}

const menuItems = [
  {
    category: 'Hot Links',
    items: [
      {
        label: 'Dashboard',
        href: `${WOSA_ADMIN_URL}dashboard`,
      },
      {
        label: 'Front End Website',
        href: WOSA_BASE_URL,
      },
    ],
  },
  {
    category: 'Global Masters',
    items: [
      {
        label: 'Menu Groups',
        href: `${VC_FE_URL}masters/menu_groups`,
      },
      {
        label: 'Menus',
        href: `${VC_FE_URL}masters/menus`,
      },
    ],
  },
];

const selectSession = (state: UnknownRecord) => state.session;
const selectMenuBookmarks = createSelector(
  [selectSession],
  (session) => session.menuBookmarks || [],
);
const selectRecentVisitedMenus = createSelector(
  [selectSession],
  (session) => session.recentVisitedMenus || [],
);
const selectUser = createSelector([selectSession], (session) => session.user);

const DashboardMenu: React.FC = () => {
  const pathname = usePathname();
  const [search, setSearch] = useState('');
  const [open, setOpen] = useState(false);
  const [accessibleMenuItems, setAccessibleMenuItems] = useState<
    UnknownRecord[]
  >([]);
  const [showHeading, setShowHeading] = useState(false);
  const [showRecentTab, setShowRecentTab] = useState(false);
  const [switchState, setSwitchState] = useState(false);

  const listRefs = useRef<Record<string, HTMLUListElement | null>>({});

  const menuBookmarks = useSelector(selectMenuBookmarks);
  const recentVisitedMenus = useSelector(selectRecentVisitedMenus);
  const user = useSelector(selectUser);
  // Memoize permission parsing
  const permitted = useMemo(
    () => (user?.role_permissions ? JSON.parse(user.role_permissions) : {}),
    [user?.role_permissions],
  );

  // Fetch accessible menus
  useEffect(() => {
    const fetchAccessibleMenus = async () => {
      try {
        const response: ApiError | ApiError | UnknownRecord[] =
          await globalApiPost(
            API_ENDPOINTS.MENU_MANAGEMENT.USER_ACCESSIBLE_MENUS,
            { permitted },
          );
        setAccessibleMenuItems((response as UnknownRecord[]) || []);
        store.dispatch(setMenuItems(response || []));
      } catch (error) {
        console.error('Failed to fetch accessible menus:', error);
      }
    };

    if (open && permitted) {
      fetchAccessibleMenus();
    }
  }, [open, permitted]);

  useEffect(() => {
    const saved = localStorage.getItem('switchState');
    if (saved !== null) {
      const parsed = JSON.parse(saved);
      setSwitchState(parsed);
      setShowRecentTab(parsed);
    }
  }, []);

  const handleSwitchToggle = useCallback((checked: boolean) => {
    setSwitchState(checked);
    setShowRecentTab(checked);
    localStorage.setItem('switchState', JSON.stringify(checked));
  }, []);

  const handleMenuItemClick = useCallback(
    async (controllerAction: string, title: string, platform: string) => {
      try {
        setOpen(false);

        const fullHref = controllerAction.replace(/^\/+/, '');
        const stored: VisitedPage[] | UnknownRecord =
          store.getState().session.recentVisitedMenus || [];

        const filtered = stored.filter(
          (p: UnknownRecord) => p.href !== fullHref,
        );

        const updated = [
          { href: fullHref, title, platform },
          ...filtered,
        ].slice(0, 10);

        await globalApiPost<UnknownRecord[]>(
          API_ENDPOINTS.USER.RECENT_VISITED_MENUS,
          { recentVisitedMenus: updated },
        );

        store.dispatch(
          hydrateSession({
            recentVisitedMenus: updated,
          }),
        );
      } catch (err) {
        console.error('Failed to update recent visited menus:', err);
      }
    },
    [],
  );

  const handleHeadingClick = useCallback(
    (groupId: string) => {
      if (!showHeading) return;

      setSearch('');
      setShowHeading(false);

      requestAnimationFrame(() => {
        const el = listRefs.current[groupId];
        if (!el) return;

        const getScrollParent = (node: Element | null): Element | Window => {
          if (!node) return window;
          let parent: Element | null = node.parentElement;

          while (parent) {
            const style = getComputedStyle(parent);
            const overflowY = style.overflowY;
            const canScroll =
              (overflowY === 'auto' ||
                overflowY === 'scroll' ||
                overflowY === 'overlay') &&
              parent.scrollHeight > parent.clientHeight;
            if (canScroll) return parent;
            parent = parent.parentElement;
          }
          return window;
        };

        const offset = 50;
        const scrollParent = getScrollParent(el);

        if (scrollParent === window) {
          const targetTop = el.getBoundingClientRect().top + window.scrollY;
          const top = Math.max(0, targetTop - offset);
          window.scrollTo({ top, behavior: 'smooth' });
        } else {
          const parentEl = scrollParent as Element;
          const parentRect = parentEl.getBoundingClientRect();
          const elRect = el.getBoundingClientRect();
          const relativeTop = elRect.top - parentRect.top + parentEl.scrollTop;
          const top = Math.max(0, relativeTop - offset);
          parentEl.scrollTo({ top, behavior: 'smooth' });
        }

        const wrapper = el.closest('.main-group');
        if (wrapper) {
          wrapper.classList.add('highlight-scroll');
          setTimeout(() => {
            wrapper.classList.remove('highlight-scroll');
          }, 2000);
        }
      });
    },
    [showHeading],
  );

  const filteredMenuItems = useMemo(
    () =>
      menuItems
        .map((section) => ({
          ...section,
          filteredItems: section.items.filter((item) =>
            item.label.toLowerCase().includes(search),
          ),
          isCategoryMatch: section.category.toLowerCase().includes(search),
        }))
        .filter(
          (section) =>
            !search ||
            section.isCategoryMatch ||
            section.filteredItems.length > 0,
        ),
    [search],
  );

  const renderStaticMenuItems = useMemo(
    () =>
      filteredMenuItems.map((section) => (
        <Text
          key={section.category}
          className={`main-group ${showHeading ? 'main-active' : 'main-inactive'}`}
        >
          {(showHeading || (!showHeading && !search)) && (
            <Text
              className={`sub-menu-heading ${showHeading ? 'parent-active' : 'parent-inactive'}`}
              onClick={() => setShowHeading(false)}
            >
              {section.category}
            </Text>
          )}

          {!showHeading && (
            <ul
              className={`sub-menu-list ${search ? 'search-active' : 'search-inactive'}`}
            >
              {section.filteredItems.map((item) => (
                <li key={item.label}>
                  {item.href ? (
                    <Link href={item.href} onClick={() => setOpen(false)}>
                      {item.label}
                    </Link>
                  ) : (
                    <span
                      onClick={() => setOpen(false)}
                      className="cursor-pointer"
                    >
                      {item.label}
                    </span>
                  )}
                </li>
              ))}
            </ul>
          )}
        </Text>
      )),
    [filteredMenuItems, showHeading, search],
  );

  const renderAccessibleMenuItems = useMemo(
    () =>
      accessibleMenuItems.map((group) => {
        const actions =
          group.menus?.flatMap((menu: UnknownRecord) => menu.actions || []) ??
          [];
        const filteredActions = actions.filter(
          (action: UnknownRecord) =>
            action.is_visible === 1 &&
            action.title.toLowerCase().includes(search),
        );
        const isCategoryMatch = group.name.toLowerCase().includes(search);

        if (search && !isCategoryMatch && filteredActions.length === 0)
          return null;

        return (
          <Text
            key={group.id}
            className={`main-group ${showHeading ? 'main-active' : 'main-inactive'}`}
          >
            {(showHeading || (!showHeading && !search)) && (
              <Text
                className={`sub-menu-heading ${showHeading ? 'parent-active' : 'parent-inactive'}`}
                onClick={() => handleHeadingClick(group.id)}
              >
                {group.name}
              </Text>
            )}

            {!showHeading && (
              <ul
                ref={(el) => {
                  listRefs.current[group.id] = el;
                }}
                className={`sub-menu-list ${search ? 'search-active' : 'search-inactive'}`}
              >
                {group.menus?.map((menu: UnknownRecord) =>
                  menu.actions
                    ?.filter(
                      (action: UnknownRecord) =>
                        action.is_visible === 1 &&
                        action.title.toLowerCase().includes(search),
                    )
                    ?.map((action: UnknownRecord) => {
                      const BASEURL =
                        String(action.platform) === '2'
                          ? VC_FE_URL
                          : WOSA_ADMIN_URL;
                      const href = `${BASEURL}${menu.controller}/${action.action}`;
                      const isActive =
                        pathname === `/${menu.controller}/${action.action}`;

                      return (
                        <li
                          key={`${menu.menu_group_id}_${menu.id}_${action.id}`}
                        >
                          <Link
                            href={href}
                            className={isActive ? 'active-menu-link' : ''}
                            onClick={() =>
                              handleMenuItemClick(
                                `${menu.controller}/${action.action}`,
                                action.title,
                                action.platform,
                              )
                            }
                          >
                            {action.title}
                          </Link>
                        </li>
                      );
                    }),
                )}
              </ul>
            )}
          </Text>
        );
      }),
    [
      accessibleMenuItems,
      search,
      showHeading,
      handleHeadingClick,
      handleMenuItemClick,
      pathname,
    ],
  );

  return (
    <Sheet open={open} onOpenChange={setOpen}>
      <SheetTrigger asChild>
        <button
          onClick={() => {
            setOpen(true);
          }}
          className="menu-trigger-button"
        >
          <CommonImage
            src="/header/nav-toggle.png"
            classname="dashboard-menu-left"
            alt="nav-toggle"
            width={20}
            height={20}
          />
        </button>
      </SheetTrigger>
      <SheetContent side="left" className="sheet-width-menu p-0">
        <SheetHeader className="menu-grid-widget">
          <div className="menu-left">
            <div className="header-title">
              <SheetTitle className="pl-4 pr-4 pb-2 pt-3">Menu</SheetTitle>
              {!showHeading && (
                <button
                  className="menu-parent-button"
                  onClick={() => setShowHeading(true)}
                >
                  <CommonImage
                    src="/main/menu_parent.webp"
                    classname="dashboard-menu-parent"
                    alt="Menu Parent"
                    width={13}
                    height={13}
                  />
                </button>
              )}
            </div>

            <Text className="input-search-cont">
              <input
                type="text"
                className="input-search-menu"
                placeholder="Search menu"
                value={search}
                onChange={(e) => setSearch(e.target.value.toLowerCase())}
              />

              {search && (
                <button
                  onClick={() => setSearch('')}
                  style={{ cursor: 'pointer' }}
                  className="clear-input-btn"
                >
                  <CommonImage
                    src="/main/cross-arrow.webp"
                    classname="clear-search-list"
                    alt="Clear Search"
                    width={12}
                    height={12}
                  />
                </button>
              )}
            </Text>

            <Text className="menu-list-cont p-4">
              {renderStaticMenuItems}
              {renderAccessibleMenuItems}
            </Text>
            <div className="dashboard-bookmarks-visited-widget">
              <div className="flex justify-between space-x-2">
                <div
                  className="text-visit"
                  onClick={() => setShowRecentTab((prev) => !prev)}
                >
                  Bookmarks & Recently Visited
                </div>
                <Switch
                  id="airplane-mode"
                  checked={switchState}
                  onCheckedChange={handleSwitchToggle}
                />
              </div>
            </div>
          </div>

          {showRecentTab && (
            <div className="bookmark-recent-menu-container menu-right">
              <div className="bookmarks-menuList sidebar">
                {recentVisitedMenus.length > 0 && (
                  <RecentVisits
                    handleMenuItemClick={handleMenuItemClick}
                    recentVisitedMenus={recentVisitedMenus}
                    setOpen={setOpen}
                  />
                )}

                {menuBookmarks.length > 0 && (
                  <Bookmarks
                    handleMenuItemClick={handleMenuItemClick}
                    menuBookmarks={menuBookmarks}
                    setOpen={setOpen}
                  />
                )}
              </div>
            </div>
          )}
        </SheetHeader>
      </SheetContent>
    </Sheet>
  );
};

export default React.memo(DashboardMenu);
