import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { NavLink, useLocation } from 'react-router-dom';

import { useAppStateContext } from '../../context/user.data.context';
import { useAccessControl } from '../../hooks/useAccessControl';

type IAppMenu = { title: string; url: string; badge?: string };

const Sidebar = (): JSX.Element => {
  const { user } = useAppStateContext();
  const location = useLocation();

  const { canAccessAllRoutes, canSeeBulkUpload } = useAccessControl(user);

  const appMenu: IAppMenu[] = useMemo(() => {
    if (!canAccessAllRoutes) {
      return [{ title: 'Pricing', url: '/pricing' }];
    }

    return [
      { title: 'Agent Analytics', url: '/agent-analytics' },
      { title: 'AI Readiness', url: '/ai-readiness' },
      { title: 'AI Visibility', url: '/ai-visibility' },
      { title: 'AI Content Generator', url: '/content-generator' },
      { title: 'Campaigns', url: '/campaigns' },
      ...(canSeeBulkUpload
        ? [
            {
              title: 'Bulk Upload',
              url: '/product-improvements',
            },
          ]
        : []),
      { title: 'Knowledge Base', url: '/knowledge-base' },
      { title: 'LLM.txt', url: '/llm' },
      { title: 'Plans', url: '/pricing' },
      { title: 'Agentic Commerce Feed', url: '/agentic-feed' },
      { title: 'Customization', url: '/' },
      { title: 'Settings', url: '/settings' },
      { title: 'Import Products', url: '/import' },
      { title: 'Support', url: '/support' },
    ];
  }, [canAccessAllRoutes, canSeeBulkUpload]);

  const scrollerRef = useRef<HTMLDivElement | null>(null);
  const itemRefs = useRef<Record<string, HTMLAnchorElement | null>>({});
  const [canScrollLeft, setCanScrollLeft] = useState(false);
  const [canScrollRight, setCanScrollRight] = useState(false);

  const updateScrollState = useCallback(() => {
    const el = scrollerRef.current;
    if (!el) return;

    const { scrollLeft, scrollWidth, clientWidth } = el;
    const left = scrollLeft > 4;
    const right = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 4;

    setCanScrollLeft(left);
    setCanScrollRight(right);
  }, []);

  const scrollByAmount = useCallback((amount: number) => {
    const el = scrollerRef.current;
    if (!el) return;
    el.scrollBy({ left: amount, behavior: 'smooth' });
  }, []);

  useEffect(() => {
    updateScrollState();

    const el = scrollerRef.current;
    if (!el) return;

    const onScroll = () => updateScrollState();
    el.addEventListener('scroll', onScroll, { passive: true });

    const onResize = () => updateScrollState();
    window.addEventListener('resize', onResize);

    return () => {
      el.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onResize);
    };
  }, [updateScrollState]);

  useEffect(() => {
    const activeItem = appMenu.find(m => {
      if (m.url === '/') return location.pathname === '/';
      return (
        location.pathname === m.url || location.pathname.startsWith(`${m.url}/`)
      );
    });

    if (!activeItem) return;

    const timeout = setTimeout(() => {
      const node = itemRefs.current[activeItem.url];
      node?.scrollIntoView({
        behavior: 'smooth',
        inline: 'center',
        block: 'nearest',
      });
    }, 50);

    return () => clearTimeout(timeout);
  }, [appMenu, location.pathname]);

  const onScrollerKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
    if (e.key === 'ArrowLeft') {
      e.preventDefault();
      scrollByAmount(-220);
    }
    if (e.key === 'ArrowRight') {
      e.preventDefault();
      scrollByAmount(220);
    }
  };

  const baseItem =
    'relative inline-flex items-center gap-2 rounded-full px-3 py-2 text-xs font-medium ' +
    'transition-all duration-200 select-none outline-none focus:outline-none [-webkit-tap-highlight-color:transparent] ' +
    'text-gray-700 hover:text-gray-900 ' +
    'hover:bg-gray-900/5 ' +
    'active:scale-[0.98]';

  const activeItem =
    'text-gray-900 bg-gray-900/5 ring-1 ring-gray-900/10 shadow-sm';

  const underline =
    'after:content-[""] after:absolute after:left-3 after:right-3 after:-bottom-1 ' +
    'after:h-[2px] after:rounded-full after:bg-gray-900/80';

  const dot =
    "before:content-[''] before:inline-block before:h-1.5 before:w-1.5 before:rounded-full before:bg-gray-900/70";

  return (
    <div className="sticky top-8 z-50 w-full border-b border-gray-200 bg-white/85 backdrop-blur supports-[backdrop-filter]:bg-white/70">
      <a
        href="#main"
        className="sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-3 focus:z-[60] rounded-md bg-white px-3 py-2 text-sm shadow ring-1 ring-gray-200 outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black/30"
      >
        Skip to content
      </a>

      <nav
        className="mx-auto w-full max-w-7xl px-4 pt-2"
        aria-label="Primary navigation"
      >
        <div className="relative">
          <div
            className={[
              'pointer-events-none absolute left-0 top-0 h-full w-10 z-10',
              'bg-gradient-to-r from-white/95 to-transparent',
              canScrollLeft ? 'opacity-100' : 'opacity-0',
              'transition-opacity',
            ].join(' ')}
          />
          <div
            className={[
              'pointer-events-none absolute right-0 top-0 h-full w-10 z-10',
              'bg-gradient-to-l from-white/95 to-transparent',
              canScrollRight ? 'opacity-100' : 'opacity-0',
              'transition-opacity',
            ].join(' ')}
          />

          {canScrollLeft && (
            <button
              type="button"
              onClick={() => scrollByAmount(-260)}
              className="absolute left-0 top-1/2 -translate-y-1/2 z-20 inline-flex h-8 w-8 items-center justify-center rounded-full bg-white/90 shadow-sm ring-1 ring-gray-200 hover:bg-white outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black/30"
              aria-label="Scroll navigation left"
            >
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
                <path
                  d="M15 18l-6-6 6-6"
                  stroke="currentColor"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                />
              </svg>
            </button>
          )}

          {canScrollRight && (
            <button
              type="button"
              onClick={() => scrollByAmount(260)}
              className="absolute right-0 top-1/2 -translate-y-1/2 z-20 inline-flex h-8 w-8 items-center justify-center rounded-full bg-white/90 shadow-sm ring-1 ring-gray-200 hover:bg-white outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black/30"
              aria-label="Scroll navigation right"
            >
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
                <path
                  d="M9 6l6 6-6 6"
                  stroke="currentColor"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                />
              </svg>
            </button>
          )}

          <div
            ref={scrollerRef}
            tabIndex={0}
            onKeyDown={onScrollerKeyDown}
            className={[
              'overflow-x-auto overflow-y-hidden scroll-smooth touch-pan-x',
              '[-webkit-overflow-scrolling:touch]',
              '[scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden',
              'px-10',
              'outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black/20 focus-visible:ring-offset-2 rounded-md',
            ].join(' ')}
            aria-label="Navigation tabs (use left/right arrow keys to scroll)"
          >
            <ul className="flex items-center gap-1 py-2 w-max min-w-full justify-start lg:justify-end">
              {appMenu.map(menu => {
                const end = menu.url === '/';
                return (
                  <li key={menu.url} className="flex-shrink-0">
                    <NavLink
                      to={menu.url}
                      end={end}
                      ref={node => {
                        itemRefs.current[menu.url] = node;
                      }}
                      className={({ isActive }) =>
                        [
                          baseItem,
                          isActive ? activeItem : '',
                          isActive ? underline : '',
                          isActive ? dot : '',
                          'max-w-[14rem] truncate focus:outline-none focus:ring-0', // Added focus-killing classes directly to the link here just to be absolutely safe
                        ]
                          .filter(Boolean)
                          .join(' ')
                      }
                      title={menu.title}
                    >
                      <span className="truncate">{menu.title}</span>

                      {menu.badge && (
                        <span className="ml-1 inline-flex items-center rounded-full bg-gray-900/10 px-2 py-0.5 text-[10px] font-semibold text-gray-900">
                          {menu.badge}
                        </span>
                      )}
                    </NavLink>
                  </li>
                );
              })}
            </ul>
          </div>
        </div>
      </nav>
    </div>
  );
};

export default Sidebar;
