import styled from '@emotion/styled';
import { setIn } from 'lodash-redux-immutability';
import { observer } from 'mobx-react-lite';
import {
  CSSProperties,
  Dispatch,
  SetStateAction,
  useCallback,
  useEffect,
  useState,
} from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import { HeaderContainer } from '@/app/(root)/create/createV2/componentsQ3/CreateHeader';
import StudioCreateForm from '@/app/(root)/create/createV2/componentsQ3/StudioCreateForm';
import { FocusedObjectContext } from '@/app/(root)/create/v2/useFocusedObject';
import StudioContext from '@/components/studio/StudioContext';
import { useContextSelector } from '@/hooks/useContextSelector';
import { ExtendLeftIcon, SlidersIcon } from '@/icons';

import StudioClipBrowser from '../clipBrowser/StudioClipBrowser';
import {
  getLibraryDefaultClipBrowserFilters,
  getWorkspaceDefaultClipBrowserFilters,
} from '../clipBrowser/defaultClipBrowserFilters';
import { BooleanFilter } from '../clipBrowser/types';
import { ClipBrowserContextProvider } from '../clipBrowser/useClipBrowser';
import { ContextMenu } from '../contextMenu/ContextMenu';
import FocusedObjectPanel from '../focusedObjectPanel/FocusedObjectPanel';
import {
  Divider,
  HorizontalPanelGroup,
  Panel,
  VerticalPanelGroup,
} from '../panelSystem/PanelSystem';
import PanelButton from './PanelButton';
import StudioLifecycleLogger from './StudioLifecycleLogger';
import {
  ThickGapHorizontalDivider,
  ThickGapVerticalDivider,
  headerPanelSize,
  oneFRPanelSize,
} from './StudioPanelUtilities';
import StudioProjectsModal from './StudioProjectsModal';
import StudioTimeline from './StudioTimeline';
import StudioToolbar from './StudioToolbar';
import { PlayButtonOnlyTransport } from './StudioTransport';
import makePanelSize from './makePanelSize';
import useFocusedObjectSync from './useFocusedObjectSync';
import useStudioLayoutManager, {
  StudioLayoutManagerContext,
} from './useStudioLayoutManager';

const panelStyle: CSSProperties = {
  overflow: 'hidden',
  position: 'relative',
  zIndex: 1,
};

const Wrapper = styled.div`
  position: relative;
  height: 100%;
  width: 100%;
  max-height: 100svh;
`;

const MainPanel = styled.div<{ sharpLeft?: boolean; sharpRight?: boolean }>`
  height: 100%;
  width: 100%;
  max-width: 100%;
  border-radius: 24px;
  min-width: 0;
  overflow: hidden;
  background-color: var(--color-background-primary);
  position: relative;
`;

const MainContentPanels = styled.div`
  height: 100%;
  padding: 0 5px;
  background-color: var(--color-background-secondary);
`;

export default observer(function StudioLayoutV2({
  setShowNav,
  showNav,
}: {
  setShowNav: Dispatch<SetStateAction<boolean>>;
  showNav: boolean;
}) {
  const workspaceId = useContextSelector(
    StudioContext,
    (context) => context.projectId
  );
  const onFocusStudioClip = useContextSelector(
    StudioContext,
    (context) => context.onFocusStudioClip
  );
  const focusedObject = useContextSelector(
    FocusedObjectContext,
    (context) => context.focusedObject
  );

  const contextMenuConfig = useContextSelector(
    StudioContext,
    (context) => context.timelineController.contextMenuConfig
  );
  const setContextMenuConfig = useContextSelector(
    StudioContext,
    (context) => context.timelineController.setContextMenuConfig
  );

  const { session } = useStores();

  useFocusedObjectSync();

  const layoutManagerContext = useStudioLayoutManager(showNav, setShowNav);

  const {
    layoutMode,
    createPanelExpanded,
    libraryPanelExpanded,
    sessionPanelExpanded,
    focusedObjectPanelExpanded,
    setFocusedObjectPanelExpanded,
    setCreatePanelExpanded,
    setLibraryPanelExpanded,
    setSessionPanelExpanded,
    createPanelSize,
    libraryPanelSize,
    sessionPanelSize,
    createPanelMinSizePx,
    libraryPanelMinSizePx,
    sessionPanelMinSizePx,
    setUserCreatePanelSize,
    setHorizontalUserLibraryPanelSize,
    verticalTopPanelSize,
    setVerticalTopPanelSize,
  } = layoutManagerContext;

  useEffect(() => {
    return onFocusStudioClip(() => setFocusedObjectPanelExpanded(true));
  }, [onFocusStudioClip, setFocusedObjectPanelExpanded]);

  useEffect(() => {
    if (focusedObject?.type === 'clip') {
      setFocusedObjectPanelExpanded(true);
    }
  }, [focusedObject, setFocusedObjectPanelExpanded]);

  const userId = session.user?.id;
  const [allSongs, setAllSongs] = useState<boolean>(false);

  const getDefaultFilters = useCallback(() => {
    let filters = allSongs
      ? getLibraryDefaultClipBrowserFilters(userId)
      : getWorkspaceDefaultClipBrowserFilters(userId, workspaceId);
    filters = setIn(filters, ['fromStudioProject'], {
      presence: BooleanFilter.Any,
    });
    return filters;
  }, [userId, workspaceId, allSongs]);

  const [projectsModalOpen, setProjectsModalOpen] = useState(false);

  useEffect(() => {
    document.body.style.overscrollBehavior = 'none';
    document.documentElement.style.overscrollBehavior = 'none';
    return () => {
      document.body.style.overscrollBehavior = '';
      document.documentElement.style.overscrollBehavior = '';
    };
  }, []);

  const [learnModalOpen, setLearnModalOpen] = useState(false);

  return (
    <StudioLayoutManagerContext.Provider value={layoutManagerContext}>
      <ClipBrowserContextProvider
        getDefaultFilters={getDefaultFilters}
        memorizeFilters
      >
        <StudioLifecycleLogger />
        <Wrapper>
          {projectsModalOpen && (
            <StudioProjectsModal onClose={() => setProjectsModalOpen(false)} />
          )}
          {contextMenuConfig && (
            <ContextMenu clientCoords={contextMenuConfig.clientCoords}>
              {
                <contextMenuConfig.ChildComponent
                  key={'context-menu-contents'}
                  {...contextMenuConfig.otherProps}
                  onClose={() => {
                    setContextMenuConfig(null);
                  }}
                />
              }
            </ContextMenu>
          )}
          <VerticalPanelGroup>
            <Panel size={headerPanelSize}>
              <StudioToolbar setLearnModalOpen={setLearnModalOpen} />
            </Panel>
            <Divider influence='neither'>
              <ThickGapHorizontalDivider />
            </Divider>
            <Panel size={oneFRPanelSize}>
              <MainContentPanels>
                {layoutMode === 'horizontal' ? (
                  <HorizontalPanelGroup>
                    <Panel
                      style={panelStyle}
                      minSizePx={createPanelMinSizePx}
                      size={createPanelSize}
                      setSize={(newSize) => {
                        if (newSize.count > 70) {
                          setCreatePanelExpanded(true);
                          setUserCreatePanelSize(newSize);
                        }
                      }}
                    >
                      <MainPanel
                        ref={layoutManagerContext.createPanelWrapperRef}
                      >
                        <StudioCreateForm
                          expanded={createPanelExpanded}
                          setExpanded={setCreatePanelExpanded}
                        />
                      </MainPanel>
                    </Panel>
                    <Divider influence='before'>
                      <ThickGapVerticalDivider />
                    </Divider>
                    <Panel
                      style={panelStyle}
                      minSizePx={libraryPanelMinSizePx}
                      size={libraryPanelSize}
                      setSize={(newSize) => {
                        if (newSize.count > 70) {
                          setLibraryPanelExpanded(true);
                          setHorizontalUserLibraryPanelSize(newSize);
                        }
                      }}
                    >
                      <MainPanel
                        ref={layoutManagerContext.libraryPanelWrapperRef}
                      >
                        <StudioClipBrowser
                          setAllSongs={setAllSongs}
                          expanded={libraryPanelExpanded}
                          setExpanded={setLibraryPanelExpanded}
                        />
                      </MainPanel>
                    </Panel>
                    <Divider influence='before'>
                      <ThickGapVerticalDivider />
                    </Divider>
                    <Panel
                      style={panelStyle}
                      size={sessionPanelSize}
                      minSizePx={sessionPanelMinSizePx}
                      setSize={(newSize) => {
                        if (newSize.count < 200) {
                          setSessionPanelExpanded(false);
                        }
                      }}
                    >
                      <MainPanel
                        ref={layoutManagerContext.sessionPanelWrapperRef}
                      >
                        {sessionPanelExpanded ? (
                          <StudioTimeline
                            setProjectsModalOpen={setProjectsModalOpen}
                            setFocusedObjectSidebarExpanded={
                              setFocusedObjectPanelExpanded
                            }
                            focusedObjectSidebarExpanded={
                              focusedObjectPanelExpanded
                            }
                            setExpanded={setSessionPanelExpanded}
                            learnModalOpen={learnModalOpen}
                          />
                        ) : (
                          <>
                            <HeaderContainer borderBottom slim center>
                              <PanelButton
                                Icon={SlidersIcon}
                                HoverIcon={ExtendLeftIcon}
                                onClick={() => setSessionPanelExpanded(true)}
                              />
                            </HeaderContainer>
                            <div className='absolute right-0 bottom-0 left-0 h-[50px]'>
                              <PlayButtonOnlyTransport />
                            </div>
                          </>
                        )}
                      </MainPanel>
                    </Panel>
                    {focusedObjectPanelExpanded && (
                      <>
                        <Divider influence='neither'>
                          <ThickGapVerticalDivider />
                        </Divider>
                        <Panel size={makePanelSize(304)}>
                          <div
                            className='-mt-[1px] -mb-[1px] h-full w-full overflow-hidden rounded-[16px] bg-background-secondary'
                            ref={
                              layoutManagerContext.focusedObjectPanelWrapperRef
                            }
                          >
                            <FocusedObjectPanel
                              onCollapse={() =>
                                setFocusedObjectPanelExpanded(false)
                              }
                            />
                          </div>
                        </Panel>
                      </>
                    )}
                  </HorizontalPanelGroup>
                ) : (
                  <VerticalPanelGroup>
                    <Panel
                      size={verticalTopPanelSize}
                      minSizePx={200}
                      maxSizePx={
                        typeof window === 'undefined'
                          ? Infinity
                          : window.innerHeight - 300
                      }
                      setSize={(newSize) => {
                        setVerticalTopPanelSize(newSize);
                      }}
                    >
                      <HorizontalPanelGroup>
                        <Panel
                          style={panelStyle}
                          minSizePx={createPanelMinSizePx}
                          size={createPanelSize}
                          setSize={(newSize) => {
                            setUserCreatePanelSize(newSize);
                          }}
                        >
                          <MainPanel
                            ref={layoutManagerContext.createPanelWrapperRef}
                          >
                            <StudioCreateForm expanded />
                          </MainPanel>
                        </Panel>
                        <Divider influence='before'>
                          <ThickGapVerticalDivider />
                        </Divider>
                        <Panel
                          style={panelStyle}
                          minSizePx={libraryPanelMinSizePx}
                          size={oneFRPanelSize}
                        >
                          <MainPanel
                            ref={layoutManagerContext.libraryPanelWrapperRef}
                          >
                            <StudioClipBrowser
                              expanded={libraryPanelExpanded}
                              setAllSongs={setAllSongs}
                            />
                          </MainPanel>
                        </Panel>
                        <Divider influence='before'>
                          <ThickGapVerticalDivider />
                        </Divider>
                        <Panel size={makePanelSize(304)}>
                          <div
                            className='-mt-[1px] -mb-[1px] h-full w-full overflow-hidden rounded-[16px] bg-background-secondary'
                            ref={
                              layoutManagerContext.focusedObjectPanelWrapperRef
                            }
                          >
                            <FocusedObjectPanel closable={false} />
                          </div>
                        </Panel>
                      </HorizontalPanelGroup>
                    </Panel>
                    <Divider influence='before'>
                      <ThickGapHorizontalDivider />
                    </Divider>
                    <Panel
                      style={panelStyle}
                      size={oneFRPanelSize}
                      minSizePx={200}
                    >
                      <MainPanel
                        ref={layoutManagerContext.sessionPanelWrapperRef}
                      >
                        <StudioTimeline
                          setProjectsModalOpen={setProjectsModalOpen}
                          learnModalOpen={learnModalOpen}
                        />
                      </MainPanel>
                    </Panel>
                  </VerticalPanelGroup>
                )}
              </MainContentPanels>
            </Panel>
            <Divider influence='neither'>
              <ThickGapHorizontalDivider />
            </Divider>
          </VerticalPanelGroup>
        </Wrapper>
      </ClipBrowserContextProvider>
    </StudioLayoutManagerContext.Provider>
  );
});
