'use client';

import { ThemeProvider } from '@emotion/react';
import styled from '@emotion/styled';
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import SideNav from '@/components/section/SideNav';
import { AudioInputStreamContextProvider } from '@/components/studio/AudioInputStreamContext';
import { DSPModuleContextProvider } from '@/components/studio/DSPModuleContext';
import MobileStudioFallback from '@/components/studio/MobileStudioFallback';
import StudioLayoutV2 from '@/components/studio/StudioLayoutV2';
import { StudioLoadingCompleter } from '@/components/studio/StudioLoadingOverlay';
import queryClient from '@/components/studio/queryClient';
import { useBreakpointMd } from '@/hooks/useBreakpoint';
import { useQueueFocusSync } from '@/hooks/useQueueFocusSync';
import { PlanFeature } from '@/state/sessionStore';
import { isMobileBrowser } from '@/utils/device';
import { isDevOrStaging } from '@/utils/environment';
import { isFeatureEnabledForPlan } from '@/utils/session';

import { StudioContextProvider } from '../../../components/studio/StudioContext';
import { StudioCreateContextProvider } from '../create/createV2/componentsQ3/StudioCreateContext';
import { compactTheme } from '../create/createV2/componentsQ3/themes';
import {
  FocusedObjectContext,
  useFocusedObject,
} from '../create/v2/useFocusedObject';
import { StudioProjectInitializer } from './StudioProjectInitializer';

const hasLocalStorage = typeof localStorage !== 'undefined';

const persister = createSyncStoragePersister({
  storage: hasLocalStorage ? localStorage : undefined,
});

const Wrapper = styled.div`
  position: relative;
  width: 100vw;
  height: 100vh;
  background-color: var(--color-background-primary);
`;

export default observer(function StudioClient() {
  const { playbar, session } = useStores();

  useEffect(() => {
    playbar.unsetClip();
  }, [playbar.clip, playbar.unsetClip]);

  useEffect(() => {
    document.body.style.overscrollBehaviorX = 'contain';
    document.body.parentElement!.style.overscrollBehaviorX = 'contain';

    return () => {
      document.body.style.overscrollBehaviorX = '';
      document.body.parentElement!.style.overscrollBehaviorX = '';
    };
  });

  const flagState = session.flags && Boolean(session.flags['studio']);
  const focusedObjectContext = useFocusedObject();
  const [showNav, setShowNav] = useState(!isDevOrStaging);
  const userId = session.user?.id;

  const isMobile = !useBreakpointMd();
  const isMobileBrowserCheck = isMobileBrowser();

  // Sync playbar queue state with focused object
  useQueueFocusSync(focusedObjectContext);

  if (flagState === false) {
    window.location.href = '/create?codr=1';
    return null;
  } else if (flagState !== true) {
    return null;
  }

  if (!userId || !session.isSubLoaded) {
    return null;
  }

  if (!isFeatureEnabledForPlan(session, PlanFeature.Studio)) {
    window.location.href = '/create?codr=1&upgrade_for_studio=true';
    return null;
  }

  if (isMobile || isMobileBrowserCheck) {
    return <MobileStudioFallback />;
  }

  return (
    <ThemeProvider theme={compactTheme}>
      <AudioInputStreamContextProvider>
        <FocusedObjectContext.Provider value={focusedObjectContext}>
          <PersistQueryClientProvider
            client={queryClient}
            persistOptions={{ persister }}
          >
            <StudioProjectInitializer userId={userId}>
              {({ loadedProject }) => (
                <DSPModuleContextProvider>
                  <StudioContextProvider
                    studioProject={loadedProject!}
                    mode='studio'
                  >
                    <StudioLoadingCompleter />
                    <StudioCreateContextProvider>
                      {showNav && (
                        <SideNav
                          mountCollapsed={!isDevOrStaging}
                          collapsible={!isDevOrStaging}
                          className='fixed top-0 bottom-0 left-0 z-50'
                        />
                      )}
                      <Wrapper>
                        <StudioLayoutV2
                          setShowNav={setShowNav}
                          showNav={showNav}
                        />
                      </Wrapper>
                    </StudioCreateContextProvider>
                  </StudioContextProvider>
                </DSPModuleContextProvider>
              )}
            </StudioProjectInitializer>
          </PersistQueryClientProvider>
        </FocusedObjectContext.Provider>
      </AudioInputStreamContextProvider>
    </ThemeProvider>
  );
});
