import { AutoFocus } from '@/mainview/components/AutoFocus';
import { FilterUI } from '@/mainview/components/Filters';
import { HeaderUI } from '@/mainview/components/Header';
import HeaderSearchField from '@/mainview/components/HeaderSearchField';
import SelectMenu from '@/mainview/components/SelectMenu';
import { FloatingShortcuts } from '@/mainview/components/Shortcuts';
import { StoreContext } from '@/mainview/scripts/contexts';
import { gameQuery } from '@/mainview/scripts/queries/romm';
import { storeEmulatorDetailsQuery } from '@/mainview/scripts/queries/store';
import { GamePadButtonCode, useShortcuts } from '@/mainview/scripts/shortcuts';
import { HandleGoBack, mobileCheck, useStickyDataAttr } from '@/mainview/scripts/utils';
import { FocusContext, useFocusable } from '@noriginmedia/norigin-spatial-navigation';
import { useQueryClient } from '@tanstack/react-query';
import { useMatchRoute, useRouter } from '@tanstack/react-router';
import { createFileRoute, Outlet } from '@tanstack/react-router';
import { zodValidator } from '@tanstack/zod-adapter';
import { DownloadCloud, Gamepad2, Home, Joystick, Puzzle } from 'lucide-react';
import { useRef } from 'react';
import { useSessionStorage } from 'usehooks-ts';
import z from 'zod';

export const Route = createFileRoute('/store/tab')({
  component: RouteComponent,
  validateSearch: zodValidator(z.object({ focus: z.string().optional() })),
  staticData: {
    enterSound: 'openStore',
    enterHaptic: 'navigateStore'
  }
});

function useIsSettings (subPath: string)
{
  "use no memo";
  const matchRoute = useMatchRoute();
  const isSettings = !!matchRoute({
    to: `/store/tab/${subPath}` as any
  });
  return isSettings;
}

function TopArea (data: { filters: Record<string, FilterOption>; })
{
  const router = useRouter();
  const { ref, focusKey } = useFocusable({
    focusKey: 'top-area',
    preferredChildFocusKey: `store-tabs`,
    onFocus: () =>
    {
      (ref.current as HTMLElement).scrollIntoView({ behavior: 'smooth', block: 'end' });
    }
  });

  useShortcuts("STORE_ROOT", () => [{
    label: "Return",
    action: (e) => HandleGoBack(router, e),
    button: GamePadButtonCode.B
  }], [router]);

  const handleNavigate = (s: string) =>
  {
    router.navigate({ to: `/store/tab/${s === 'home' ? '' : s}`, viewTransition: { types: ['slide-up'] }, replace: true });
  };

  return <div ref={ref}>
    <FocusContext value={focusKey}>
      <div className='w-full'>
        <FilterUI rootFocusKey='STORE_ROOT' containerClassName='flex w-full justify-center' id="store-tabs" options={data.filters}
          setSelected={handleNavigate} />
      </div>
    </FocusContext>
  </div>;
}

function StoreOutlet ()
{
  const { ref, focusKey } = useFocusable({ focusKey: "STORE_OUTLET" });
  return <div ref={ref}>
    <FocusContext value={focusKey}>
      <Outlet />
    </FocusContext>
  </div>;
}

function RouteComponent ()
{
  // Root spatial nav container
  const router = useRouter();
  const { ref, focusKey, focusSelf } = useFocusable({
    focusKey: "STORE_ROOT",
    preferredChildFocusKey: 'top-area',
    forceFocus: true
  });
  const queryClient = useQueryClient();
  const headerRef = useRef(null);
  const sentinelRef = useRef(null);
  const filters: Record<string, FilterOption> = {
    home: { label: "Home", icon: <Home />, selected: useIsSettings(''), },
    emulators: { label: "Emulators", icon: <Joystick />, selected: useIsSettings('emulators') },
    games: { label: "Games", icon: <Gamepad2 />, selected: useIsSettings('games') },
    download: { label: "Download", icon: <DownloadCloud />, selected: useIsSettings('download') },
    plugins: { label: "Plugins", icon: <Puzzle />, selected: useIsSettings('plugins') }
  };
  const [search, setSearch] = useSessionStorage<string | undefined>(`${router.history.location.pathname}-search`, undefined);
  const [, setGamesSearch] = useSessionStorage<string | undefined>(`/store/tab/games-search`, undefined);

  const handleDetails = (type: string, source: string, id: string, focus: string) =>
  {
    if (type === 'emulator')
    {
      if (!source || source === 'local') return;
      router.navigate({ to: '/store/details/emulator/$id', params: { id } });
    }
    else if (type === 'game')
    {
      router.navigate({ to: '/game/$source/$id', params: { source: source, id: id } });
    }
  };

  const handlePrefetch = (type: string, source: string, id: string) =>
  {
    if (type === 'emulator')
    {
      queryClient.prefetchQuery(storeEmulatorDetailsQuery(id));
    }
    else if (type === 'game')
    {
      queryClient.prefetchQuery(gameQuery(source, id));
    }
  };

  const handleSearch = (search: string | undefined) =>
  {
    if (filters['home'].selected)
    {
      setGamesSearch(search);
      router.navigate({ to: '/store/tab/games', replace: true, viewTransition: { types: ['slide-up'] } });
    } else
    {
      setSearch(search);
    }

  };

  const isMobile = mobileCheck();
  useStickyDataAttr(headerRef, sentinelRef, ref);

  return <div ref={ref} className='overflow-y-scroll w-screen h-screen' >
    <StoreContext value={{ showDetails: handleDetails, prefetchDetails: handlePrefetch }} >
      <FocusContext.Provider value={focusKey}>
        <div className="relative flex flex-col min-h-screen text-base-content z-10" >
          <div ref={sentinelRef} className="h-0" />
          <div ref={headerRef} className='sticky p-2 group top-0 not-mobile:data-stuck:backdrop-blur-xl z-15 mobile:data-stuck:bg-base-300'>
            <HeaderUI buttonElements={<HeaderSearchField compact={useIsSettings('')} id={'store-search'} search={search} onSubmit={handleSearch} />} />
          </div>
          <TopArea filters={filters} />
          <StoreOutlet />
          {!isMobile && <>
            <div className='bg-gradient'></div>
            <div className='bg-noise'></div>
            <div className='bg-dots'></div>
          </>}
        </div>
        <SelectMenu rootFocusKey={focusKey} />
      </FocusContext.Provider>
    </StoreContext>
    <AutoFocus focus={focusSelf} />
    <FloatingShortcuts />
  </div >;
}
