import { memo } from 'react';

import type { ReactNode, RefObject } from 'react';
import type { ClickableOnClick } from '../Clickable';
import type { TransitionInOut2Api } from '../TransitionInOut2';

import useAppShell from '~/src/components/NextApp/lib/useAppShell';
import { toRgba } from '~/src/lib/utils/color';
import BackButton from '../BackButton';
import Box from '../Box';
import Clickable from '../Clickable';
import Divider from '../Divider';
import FadeOnMount from '../FadeOnMount';
import Gradient from '../Gradient';
import { HydrationGuard } from '../HydrationGuard';
import ChevronIcon from '../Icon/ChevronIcon';
import MenuIcon from '../Icon/MenuIcon';
import MoreIcon from '../Icon/MoreIcon';
import TransitionInOut2 from '../TransitionInOut2';

export const PAGE_HEADER_HEIGHT = '6.8rem';

export const ICON_SIZE = '3.8rem';
const HORIZONTAL_PADDING = '1.4rem';

export type PageHeaderRenderRight = () => ReactNode;

export interface PageHeaderProps {
  onMoreClick?: ClickableOnClick;
  renderRight?: PageHeaderRenderRight;
  renderLeft?: () => ReactNode;
  withGradient?: boolean;
  gradientApiRef?: RefObject<TransitionInOut2Api | null>;
  gradientIsVisibleInitial?: boolean;
  withMenuButton?: boolean;
  withBackButton?: boolean;
  backHref?: string;
  children?: ReactNode;
  backgroundColor?: string;
}

const PageHeader = memo<PageHeaderProps>(
  ({
    onMoreClick,
    renderRight,
    renderLeft,
    withGradient = true,
    gradientApiRef,
    gradientIsVisibleInitial,
    children,
    withMenuButton = false,
    withBackButton = true,
    backgroundColor = '#000',
    backHref,
  }) => {
    const { openAppDrawer } = useAppShell();

    const renderRightInternal = () => {
      if (onMoreClick) {
        return (
          <Clickable
            testId="openActionMenu"
            onClick={onMoreClick}
            title="Open actions menu"
            centerContent
            fullWidth
            fullHeight
          >
            <MoreIcon size="1em" />
          </Clickable>
        );
      }

      if (renderRight) {
        return renderRight();
      }
    };

    return (
      <Box
        tag="header"
        flexBox
        positionRelative
        height={PAGE_HEADER_HEIGHT}
        fullWidth
        alignCenter
        pointerEvents="none"
        zIndex={1}
        style={{
          backgroundColor: withGradient ? 'transparent' : backgroundColor,
        }}
      >
        {withGradient && (
          <TransitionInOut2
            isVisibleInitial={gradientIsVisibleInitial}
            apiRef={gradientApiRef}
            coverParent
            zIndex={-1}
            bottom="-20%"
          >
            <Gradient
              from={toRgba(backgroundColor, 0.65)}
              to={toRgba(backgroundColor, 0)}
              coverParent
            />
          </TransitionInOut2>
        )}
        <Box
          positionAbsolute
          zIndex={2}
          top={0}
          left={HORIZONTAL_PADDING}
          fullHeight
          pointerEvents="all"
        >
          <Box flexRow fullHeight positionRelative alignCenter>
            {(() => {
              if (renderLeft) {
                return renderLeft();
              }

              return (
                <>
                  {withBackButton && (
                    <BackButton href={backHref}>
                      <Box
                        flexRow
                        fullHeight
                        centerContent
                        margin={`0 0 0 ${
                          withMenuButton ? '-1.2rem' : '-.2rem'
                        }`}
                      >
                        <ChevronIcon
                          direction="left"
                          opacity={withMenuButton ? 0.5 : 0.8}
                          size="2rem"
                        />
                        {withMenuButton && (
                          <Divider
                            direction="vertical"
                            margin="0 .2rem 0 -.2rem"
                            height="50%"
                            opacity={0.2}
                          />
                        )}
                      </Box>
                    </BackButton>
                  )}
                  {withMenuButton && (
                    <HydrationGuard>
                      <FadeOnMount>
                        <Clickable
                          onClick={openAppDrawer}
                          title="Open main menu"
                          centerContent
                          fullWidth
                          fullHeight
                          testId="sideNavButton"
                        >
                          <MenuIcon size={ICON_SIZE} />
                        </Clickable>
                      </FadeOnMount>
                    </HydrationGuard>
                  )}
                </>
              );
            })()}
          </Box>
        </Box>
        <Box
          zIndex={1}
          centerContent
          style={{
            width: '100%',
            height: '100%',
            pointerEvents: withGradient ? 'none' : 'all',
            textAlign: 'center',
            contain: 'strict',
          }}
        >
          {children}
        </Box>
        <Box
          positionAbsolute
          zIndex={2}
          top={0}
          right={HORIZONTAL_PADDING}
          fullHeight
          pointerEvents="all"
        >
          {renderRightInternal()}
        </Box>
      </Box>
    );
  }
);

export default PageHeader;
