'use client';

import {
  Drawer,
  DrawerBody,
  DrawerContent,
  DrawerOverlay,
} from '@chakra-ui/react';
import { ThemeProvider } from '@emotion/react';
import { observer } from 'mobx-react-lite';
import React, { useCallback, useEffect, useRef } from 'react';
import { ErrorBoundary } from 'react-error-boundary';

import { useStores } from '@/app/(root)/AppProviders';
import { useOrpheusExperimentGroup } from '@/app/(root)/chat/hooks/useOrpheusExperimentGroup';
import { OrpheusChatProvider, useChat } from '@/app/(root)/chat/useChat';
import CreateForm from '@/app/(root)/create/createV2/componentsQ3/CreateForm';
import { standardTheme } from '@/app/(root)/create/createV2/componentsQ3/themes';
import CreateFormContext from '@/app/(root)/create/v2/CreateFormContext';
import { CreateModes } from '@/app/(root)/create/v2/types';
import { useCurrentWorkspace } from '@/app/(root)/create/v2/useCurrentWorkspace';
import { useBreakpointMd } from '@/hooks/useBreakpoint';
import { useContextSelector } from '@/hooks/useContextSelector';
import { useRemixUrlParams } from '@/hooks/useRemixUrlParams';
import { PlusIcon } from '@/icons';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '../button/Button';
import CloseButton from '../button/CloseButton';
import { getWorkspaceDefaultClipBrowserFilters } from '../clipBrowser/defaultClipBrowserFilters';
import { ClipBrowserFilters } from '../clipBrowser/types';
import { ClipBrowserContextProvider } from '../clipBrowser/useClipBrowser';

const MobileCreate: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  onOpen: () => void;
}> = observer(({ isOpen, onClose, onOpen }) => {
  const btnRef = React.useRef<HTMLButtonElement>(null);

  const { genForm, session } = useStores();

  useRemixUrlParams();

  const handleClose = () => {
    genForm.shouldOpenMobileCreate = undefined;
    onClose();
  };

  const isMobile = !useBreakpointMd();
  const { isControlGroup: isChatExpControlGroup } = useOrpheusExperimentGroup();
  const isChatExpEnabled = !isChatExpControlGroup;
  const mode = useContextSelector(
    CreateFormContext,
    (ctx) => ctx.state.global.mode
  );
  const orpheusChatState = useChat(!!isChatExpEnabled);
  const userId = session.user?.id;
  const workspaceId = useCurrentWorkspace();

  const getDefaultFilters = useCallback(
    () =>
      userId && workspaceId
        ? getWorkspaceDefaultClipBrowserFilters(userId, workspaceId)
        : null,
    [userId, workspaceId]
  );

  useEffect(() => {
    if (isMobile) {
      if (genForm.shouldOpenMobileCreate) {
        onOpen();
        genForm.shouldOpenMobileCreate = undefined;
      } else if (genForm.shouldOpenMobileCreate === false) {
        handleClose();
      }
    } else {
      handleClose();
    }
  }, [genForm.shouldOpenMobileCreate, isMobile]);

  const isOpenedState = useRef(false);

  // This is a hacky workaround to get the DrawerFooter to appear properly on mobile
  // ref: https://github.com/chakra-ui/chakra-ui/issues/2468#issuecomment-726192898
  // originally, this was defined across all pages in the tailwind.css file but was causing the url bar collapse to break
  // this conditionally applies it when the drawer is open & cleans up when the drawer is closed
  useEffect(() => {
    if (isMobile) {
      if (isOpen) {
        document.body.style.height = '100%';
        document.body.style.overflowX = 'hidden';
        document.documentElement.style.height = '100%';
        document.documentElement.style.overflowX = 'hidden';
        isOpenedState.current = true;
      } else if (isOpenedState.current) {
        document.body.style.height = 'auto';
        document.documentElement.style.height = 'auto';
        document.body.style.removeProperty('overflow-x');
        document.documentElement.style.removeProperty('overflow-x');
        isOpenedState.current = false;
      }
    }
    return () => {
      if (isOpenedState.current) {
        document.body.style.height = 'auto';
        document.documentElement.style.height = 'auto';
        document.body.style.removeProperty('overflow-x');
        document.documentElement.style.removeProperty('overflow-x');
        isOpenedState.current = false;
      }
    };
  }, [isOpen, isMobile]);

  return (
    <>
      <Drawer
        isOpen={isOpen}
        placement='bottom'
        onClose={handleClose}
        finalFocusRef={btnRef as React.RefObject<HTMLButtonElement>}
        size='lg'
        blockScrollOnMount={false} // without this, iOS text selection on any element in the create form is broken. remove at your peril.
      >
        <DrawerOverlay display={['block', 'block', 'none']} />
        <DrawerContent
          display={['flex', 'flex', 'none']}
          backgroundColor='black'
          boxShadow={'0 0 10px 5px rgba(255, 255, 255, 0.08)'}
          // this needs to be <100dvh to allow for the drawer footer to open
          // TODO: remove all the chakra here
          height={'100dvh'}
          borderRadius={'40px 40px 0 0'}
          sx={{
            transition: 'height 0.3s ease-out',
            overflowY: 'hidden',
          }}
          bg='var(--color-background-primary)'
          color='var(--color-foreground-primary)'
        >
          <div className='flex items-center justify-between px-4 py-6 text-foreground-primary'>
            {mode === CreateModes.CHAT ? (
              <div className='absolute left-4'>
                <Button
                  size={ButtonSize.Medium}
                  shape={ButtonShape.Pill}
                  variant={ButtonVariant.Standard}
                  onClick={() => {
                    orpheusChatState?.createChatSession();
                  }}
                  icon={PlusIcon}
                />
              </div>
            ) : null}
            <span className='w-full text-center font-sans text-[16px] font-normal'>
              {mode === CreateModes.CHAT ? (
                <Button
                  className='border-0 bg-transparent p-0'
                  onClick={() => {
                    if (orpheusChatState?.currentSession?.session_id) {
                      navigator.clipboard.writeText(
                        `${window.location.origin}/chat/${orpheusChatState?.currentSession?.session_id}`
                      );
                    }
                  }}
                >
                  {orpheusChatState?.currentSession?.name ?? 'New Chat'}
                </Button>
              ) : (
                'Create'
              )}
            </span>
            <div className='absolute right-4'>
              <CloseButton onClick={handleClose} />
            </div>
          </div>
          <DrawerBody
            sx={{
              padding: '0',
              overflowY: mode === CreateModes.CHAT ? undefined : 'auto',
            }}
          >
            <div
              className='mobile-create-form-wrapper'
              style={{
                padding: '0',
                margin: '0',
                width: '100%',
                height: '100%',
              }}
            >
              <ErrorBoundary
                fallback={
                  <div className='py-8 text-center text-foreground-secondary'>
                    <h2 className='mb-2 text-lg font-semibold'>
                      Create Form Error
                    </h2>
                    <p>
                      There was an error loading the Create Form. Please try
                      again later.
                    </p>
                  </div>
                }
              >
                <ThemeProvider theme={standardTheme}>
                  <ClipBrowserContextProvider
                    // should return correct type if userId and workspaceId are set.
                    getDefaultFilters={
                      getDefaultFilters as () => ClipBrowserFilters
                    }
                  >
                    <OrpheusChatProvider value={orpheusChatState}>
                      <CreateForm onMobileCreate={handleClose} />
                    </OrpheusChatProvider>
                  </ClipBrowserContextProvider>
                </ThemeProvider>
              </ErrorBoundary>
            </div>
          </DrawerBody>
        </DrawerContent>
      </Drawer>
    </>
  );
});

export default MobileCreate;
