/* eslint-disable @typescript-eslint/no-unused-vars */
import React from "react";

import { Provider } from "../../utils";
import { DeviceType } from "../../enums";

import { FloatingButton } from "../floating-button";

import SectionContainer from "./sub-components/SectionContainer";
import SubSectionHeader from "./sub-components/SectionHeader";
import SubSectionFilter from "./sub-components/SectionFilter";
import SubSectionBody from "./sub-components/SectionBody";
import SubSectionBodyContent from "./sub-components/SectionBodyContent";
import SubSectionPaging from "./sub-components/SectionPaging";
import InfoPanel from "./sub-components/InfoPanel";
import SubInfoPanelBody from "./sub-components/InfoPanelBody";
import SubInfoPanelHeader from "./sub-components/InfoPanelHeader";
import SubSectionFooter from "./sub-components/SectionFooter";
import SubSectionWarning from "./sub-components/SectionWarning";
import SubSectionSubmenu from "./sub-components/SectionSubmenu";

import { SectionProps } from "./Section.types";
import {
  SECTION_BODY_NAME,
  SECTION_FILTER_NAME,
  SECTION_FOOTER_NAME,
  SECTION_HEADER_NAME,
  SECTION_INFO_PANEL_BODY_NAME,
  SECTION_INFO_PANEL_HEADER_NAME,
  SECTION_PAGING_NAME,
  SECTION_WARNING_NAME,
  SECTION_SUBMENU_NAME,
} from "./Section.constants";
import { parseChildren } from "./Section.utils";

export type { SectionProps };

const SectionHeader = ({ children }: { children: React.ReactNode }) => null;
SectionHeader.displayName = SECTION_HEADER_NAME;

const SectionFilter = ({ children }: { children?: React.ReactNode }) => null;
SectionFilter.displayName = SECTION_FILTER_NAME;

const SectionBody = ({ children }: { children: React.ReactNode }) => null;
SectionBody.displayName = SECTION_BODY_NAME;

const SectionFooter = ({ children }: { children: React.ReactNode }) => null;
SectionFooter.displayName = SECTION_FOOTER_NAME;

const SectionPaging = ({ children }: { children: React.ReactNode }) => null;
SectionPaging.displayName = SECTION_PAGING_NAME;

const InfoPanelBody = ({ children }: { children: React.ReactNode }) => null;
InfoPanelBody.displayName = SECTION_INFO_PANEL_BODY_NAME;

const InfoPanelHeader = ({ children }: { children: React.ReactNode }) => null;
InfoPanelHeader.displayName = SECTION_INFO_PANEL_HEADER_NAME;

const SectionWarning = ({ children }: { children: React.ReactNode }) => null;
SectionWarning.displayName = SECTION_WARNING_NAME;

const SectionSubmenu = ({ children }: { children: React.ReactNode }) => null;
SectionSubmenu.displayName = SECTION_SUBMENU_NAME;

const Section = (props: SectionProps) => {
  const {
    onDrop,
    showPrimaryProgressBar,
    primaryProgressBarIcon,
    primaryProgressBarValue,
    showPrimaryButtonAlert,
    showSecondaryProgressBar,
    secondaryProgressBarValue,
    secondaryProgressBarIcon,
    showSecondaryButtonAlert,
    uploadFiles,
    viewAs,
    withBodyScroll = true,
    children,
    onOpenUploadPanel,
    isInfoPanelAvailable = true,
    settingsStudio = false,
    clearUploadedFilesHistory,
    isInfoPanelScrollLocked,
    isFormGallery,
    currentDeviceType,

    isInfoPanelVisible,
    setIsInfoPanelVisible,
    isMobileHidden,
    canDisplay,
    anotherDialogOpen,
  } = props;

  const [sectionSize, setSectionSize] = React.useState<{
    width?: number;
    height?: number;
  }>({});

  const containerRef = React.useRef<null | HTMLDivElement>(null);
  const timerRef = React.useRef<null | ReturnType<typeof setTimeout>>(null);

  const [
    sectionHeaderContent,
    sectionFilterContent,
    sectionBodyContent,
    sectionFooterContent,
    sectionPagingContent,
    sectionWarningContent,
    infoPanelBodyContent,
    infoPanelHeaderContent,
    sectionSubmenuContent,
  ]: (React.JSX.Element | null)[] = parseChildren(children);

  const isSectionHeaderAvailable = !!sectionHeaderContent;
  const isSectionFilterAvailable = !!sectionFilterContent;
  const isSectionPagingAvailable = !!sectionPagingContent;
  const isSectionSubmenuAvailable = !!sectionSubmenuContent;
  const isSectionBodyAvailable =
    !!sectionBodyContent ||
    isSectionFilterAvailable ||
    isSectionPagingAvailable;
  const isSectionAvailable =
    isSectionHeaderAvailable ||
    isSectionFilterAvailable ||
    isSectionBodyAvailable ||
    isSectionPagingAvailable;

  const onResize = React.useCallback(() => {
    if (timerRef.current) clearTimeout(timerRef.current);

    timerRef.current = setTimeout(() => {
      if (!containerRef.current) return;

      const computedStyles = window.getComputedStyle(
        containerRef.current,
        null,
      );
      const width = +computedStyles.getPropertyValue("width").replace("px", "");
      const height = +computedStyles
        .getPropertyValue("height")
        .replace("px", "");

      setSectionSize(() => ({ width, height }));
    }, 100);
  }, []);

  React.useEffect(() => {
    const elem = containerRef.current;

    window.addEventListener("resize", onResize);

    const ro = new ResizeObserver(onResize);

    if (elem) ro.observe(elem);
    return () => {
      if (elem) ro.unobserve(elem);
      window.removeEventListener("resize", onResize);
    };
  }, [onResize]);

  const showTwoProgress = showPrimaryProgressBar && showSecondaryProgressBar;

  return (
    isSectionAvailable && (
      <Provider
        value={{
          sectionWidth: sectionSize.width,
          sectionHeight: sectionSize.height,
        }}
      >
        <SectionContainer
          viewAs={viewAs}
          ref={containerRef}
          isSectionHeaderAvailable={isSectionHeaderAvailable}
          showTwoProgress={showTwoProgress}
        >
          {isSectionHeaderAvailable &&
            currentDeviceType === DeviceType.desktop && (
              <SubSectionHeader
                className="section-header_header"
                isFormGallery={isFormGallery}
              >
                {sectionHeaderContent}
              </SubSectionHeader>
            )}

          {isSectionSubmenuAvailable &&
            currentDeviceType === DeviceType.desktop && (
              <SubSectionSubmenu>{sectionSubmenuContent}</SubSectionSubmenu>
            )}
          {isSectionFilterAvailable &&
            currentDeviceType === DeviceType.desktop && (
              <SubSectionFilter
                className="section-header_filter"
                viewAs={viewAs}
              >
                {sectionFilterContent}
              </SubSectionFilter>
            )}

          {isSectionBodyAvailable && (
            <SubSectionBody
              onDrop={onDrop}
              uploadFiles={uploadFiles}
              withScroll={withBodyScroll}
              autoFocus={currentDeviceType === DeviceType.desktop}
              viewAs={viewAs}
              settingsStudio={settingsStudio}
              isFormGallery={isFormGallery}
              currentDeviceType={currentDeviceType}
            >
              {isSectionHeaderAvailable &&
                currentDeviceType !== DeviceType.desktop && (
                  <SubSectionHeader
                    className="section-body_header"
                    isFormGallery={isFormGallery}
                  >
                    {sectionHeaderContent}
                  </SubSectionHeader>
                )}
              {currentDeviceType !== DeviceType.desktop && (
                <SubSectionWarning>{sectionWarningContent}</SubSectionWarning>
              )}
              {isSectionSubmenuAvailable &&
                currentDeviceType !== DeviceType.desktop && (
                  <SubSectionSubmenu>{sectionSubmenuContent}</SubSectionSubmenu>
                )}
              {isSectionFilterAvailable &&
                currentDeviceType !== DeviceType.desktop && (
                  <SubSectionFilter
                    className="section-body_filter"
                    viewAs={viewAs}
                  >
                    {sectionFilterContent}
                  </SubSectionFilter>
                )}
              <SubSectionBodyContent>
                {sectionBodyContent}
              </SubSectionBodyContent>
              <SubSectionFooter>{sectionFooterContent}</SubSectionFooter>
              {isSectionPagingAvailable && (
                <SubSectionPaging>{sectionPagingContent}</SubSectionPaging>
              )}
            </SubSectionBody>
          )}

          {currentDeviceType === DeviceType.desktop ? (
            showTwoProgress ? (
              <div className="progress-bar_container">
                <FloatingButton
                  className="layout-progress-bar"
                  icon={primaryProgressBarIcon}
                  percent={primaryProgressBarValue}
                  alert={showPrimaryButtonAlert}
                  onClick={onOpenUploadPanel}
                  clearUploadedFilesHistory={clearUploadedFilesHistory}
                />
                <FloatingButton
                  className="layout-progress-second-bar"
                  icon={secondaryProgressBarIcon}
                  percent={secondaryProgressBarValue}
                  alert={showSecondaryButtonAlert}
                  showTwoProgress={showTwoProgress}
                />
              </div>
            ) : showPrimaryProgressBar && !showSecondaryProgressBar ? (
              <div className="progress-bar_container">
                <FloatingButton
                  className="layout-progress-bar"
                  icon={primaryProgressBarIcon}
                  percent={primaryProgressBarValue}
                  alert={showPrimaryButtonAlert}
                  onClick={onOpenUploadPanel}
                  clearUploadedFilesHistory={clearUploadedFilesHistory}
                />
              </div>
            ) : !showPrimaryProgressBar && showSecondaryProgressBar ? (
              <div className="progress-bar_container">
                <FloatingButton
                  className="layout-progress-bar"
                  icon={secondaryProgressBarIcon}
                  percent={secondaryProgressBarValue}
                  alert={showSecondaryButtonAlert}
                />
              </div>
            ) : null
          ) : null}
        </SectionContainer>

        {isInfoPanelAvailable && (
          <InfoPanel
            isVisible={isInfoPanelVisible}
            setIsVisible={setIsInfoPanelVisible}
            isMobileHidden={isMobileHidden}
            canDisplay={canDisplay}
            anotherDialogOpen={anotherDialogOpen}
            viewAs={viewAs}
            currentDeviceType={currentDeviceType}
          >
            <SubInfoPanelHeader>{infoPanelHeaderContent}</SubInfoPanelHeader>
            <SubInfoPanelBody isInfoPanelScrollLocked={isInfoPanelScrollLocked}>
              {infoPanelBodyContent}
            </SubInfoPanelBody>
          </InfoPanel>
        )}
      </Provider>
    )
  );
};

Section.SectionHeader = SectionHeader;
Section.SectionFilter = SectionFilter;
Section.SectionBody = SectionBody;
Section.SectionFooter = SectionFooter;
Section.SectionPaging = SectionPaging;
Section.InfoPanelBody = InfoPanelBody;
Section.InfoPanelHeader = InfoPanelHeader;
Section.SectionWarning = SectionWarning;
Section.SectionSubmenu = SectionSubmenu;

export default Section;
