import React, {
  Children,
  ComponentType,
  cloneElement,
  isValidElement,
  useRef,
} from 'react';
import { Cell, Layout, Page } from '@wix/design-system';
import { FormPageMainContent } from '../../components/FormPageMainContent';
import { FormPageAdditionalContent } from '../../components/FormPageAdditionalContent';
import {
  FormPageActionsBar,
  FormPageActionsBarProps,
} from '../../components/FormPage';
import { useAutoScrollOnLoad } from '../../hooks/useAutoScrollOnLoad';
import { FocusableWrapper } from '@wix/bex-utils';
import { FormFooter } from './FormFooter';
import { useIsMobile } from '../../hooks/useIsMobile';

export function useFormPageContent(
  child: JSX.Element,
  {
    elementName = 'FormPage',
    MainContentElement = FormPageMainContent,
    AdditionalContentElement = FormPageAdditionalContent,
    FooterElement = FormPageActionsBar,
    scrollableRef,
  }: {
    elementName?: string;
    MainContentElement?: ComponentType<JSX.Element>;
    AdditionalContentElement?: ComponentType<JSX.Element>;
    FooterElement?: ComponentType<FormPageActionsBarProps>;
    scrollableRef?: HTMLElement | null;
  } = {},
) {
  const childrenArray = Children.toArray(child.props.children);
  const scrollToItem = useRef<() => void>();
  const doesItemExist = useRef<() => boolean>();

  if (process.env.NODE_ENV !== 'production') {
    if (
      !childrenArray.every(
        (elem) =>
          isValidElement(elem) &&
          (elem.type === MainContentElement ||
            elem.type === AdditionalContentElement),
      )
    ) {
      throw new Error(
        `<${elementName}.Content/> must have only <${elementName}.MainContent/> and <${elementName}.AdditionalContent/> children`,
      );
    }

    if (childrenArray.length === 0 || childrenArray.length > 2) {
      throw new Error(
        `<${elementName}.Content/> must have 1 (<${elementName}.MainContent/>) or 2 (<${elementName}.MainContent/> and <${elementName}.AdditionalContent/>) children`,
      );
    }

    if (
      !isValidElement(childrenArray[0]) ||
      childrenArray[0].type !== MainContentElement
    ) {
      throw new Error(
        `<${elementName}.MainContent/> should be the first child of <${elementName}.Content/>`,
      );
    }

    if (
      childrenArray.length === 2 &&
      (!isValidElement(childrenArray[1]) ||
        childrenArray[1].type !== AdditionalContentElement)
    ) {
      throw new Error(
        `Only <${elementName}.AdditionalContent/> can be the second child of <${elementName}.Content/>`,
      );
    }
  }

  if (isValidElement(childrenArray[0])) {
    childrenArray[0] = cloneElement(
      childrenArray[0],
      {
        span: childrenArray.length === 1 ? 12 : 8,
      } as any,
      childrenArray[0].props.children,
    );
  }

  useAutoScrollOnLoad(scrollToItem, doesItemExist);
  const isMobile = useIsMobile();

  return (
    <Page.Content key={child.key}>
      <FocusableWrapper
        scrollableRef={scrollableRef}
        getScrollableTrigger={(triggerScrollable) => {
          scrollToItem.current = triggerScrollable;
        }}
        getDoesItemExist={(callback) => {
          doesItemExist.current = callback;
        }}
      >
        <Layout
          cols={isMobile ? 1 : undefined}
          gap={isMobile ? '12px 0' : undefined}
        >
          {childrenArray}
          {!isMobile && (
            <Cell>
              <FormFooter
                scrollableRef={scrollableRef}
                FooterElement={FooterElement}
              />
            </Cell>
          )}
        </Layout>
      </FocusableWrapper>
    </Page.Content>
  );
}
