import { darkLine } from '@/styles/colors';
import {
  BELOW_W_1024,
  BELOW_W_768,
  NOT_BELOW_W_1024,
  NOT_BELOW_W_768,
  contentBelowHeaderHeight,
  paddedMainContentWidth,
} from '@/styles/dimensions';
import { css, keyframes } from '@emotion/react';
import styled from '@emotion/styled';
import { ReactNode, useLayoutEffect, useRef } from 'react';
import { PaddedBlock, VerticalBlock, WhiteBackgroundPaddedBlockCSS } from './Layout';
import { Body, FeatureTitle, Subtitle } from './Typography';

const animationCSS = css`
  animation-duration: 1ms; /* Firefox requires this to apply the animation */
  animation-timeline: scroll(root);
  animation-fill-mode: both;
`;

const counterScrollKeyframes = keyframes`
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(100%);
  }
`;

const counterScrollCSS = css`
  animation-name: ${counterScrollKeyframes};
  animation-timing-function: linear;
  ${animationCSS};
`;

const FeatureSpotlightColumns = styled.div`
  display: grid;
  grid-template-columns: 55.4rem 1fr;
  height: 100%;

  @media screen and (${BELOW_W_1024}) {
    display: flex;
    flex-direction: column-reverse;
  }
`;

const DesktopAnimWrapper = styled.div`
  position: relative;
  @media screen and (${BELOW_W_768}) {
    display: none;
  }
`;

const MobileAnimWrapper = styled.div`
  position: relative;
  overflow: hidden;
  width: 100%;
  @media screen and (${NOT_BELOW_W_768}) {
    display: none;
  }
`;

const ResponsiveContainer = styled.div<{ mobileBackgroundColor: string }>`
  display: block;
  position: relative;
  @media screen and (${BELOW_W_1024}) {
    background-color: ${({ mobileBackgroundColor }) => mobileBackgroundColor};
    display: flex;
    flex-direction: column-reverse;
    justify-content: stretch;
    align-items: center;
  }
`;

const FeatureSpotlightWrapper = styled.div`
  display: block;
  height: calc(${contentBelowHeaderHeight} * 2);
  @media screen and (${BELOW_W_1024}) {
    height: auto;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    width: 100%;
    position: relative;
    overflow-x: hidden;
  }
`;

const PinnedPaddedBlock = styled(PaddedBlock)`
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  padding-right: calc(48px * 2);
  @media screen and (${BELOW_W_1024}) {
    ${WhiteBackgroundPaddedBlockCSS}
  }
  @media screen and (${NOT_BELOW_W_1024}) {
    height: ${contentBelowHeaderHeight};
    ${counterScrollCSS}
  }
  @media screen and (${BELOW_W_768}) {
    margin: 2.4rem;
    padding: 24px;
    height: auto;
    position: relative;
    transform: none;
    animation: none;
  }
`;

const FullHeightVerticalBlock = styled(VerticalBlock)`
  height: ${contentBelowHeaderHeight};
  min-width: 0;
  & + & {
    border-top: 1px solid ${darkLine};
  }
  &:before {
    border-color: transparent !important;
  }
  @media screen and (${BELOW_W_1024}) {
    height: auto;
    display: flex;
    align-items: center;
    & + & {
      border-top: none;
    }
  }
`;

const ImageContainer = styled.div`
  position: relative;
  width: 100%;
  height: 100%;
  @media screen and (${BELOW_W_1024}) {
    height: ${paddedMainContentWidth};
    > * {
      transform: scale(1.2);
    }
  }
`;

const StackWrapper = styled.div<{ fadeRightColor?: string }>`
  position: relative;
  background-color: ${({ fadeRightColor }) => fadeRightColor || 'transparent'};
  &:after {
    content: '';
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    border-left: 1px solid ${darkLine};
  }
  &:before {
    content: '';
    display: block;
    position: absolute;
    left: calc(100% - 48px);
    z-index: 0;
    right: -100svw;
    top: 0;
    bottom: 1px;
    background-image: linear-gradient(
      to right,
      transparent 0px,
      ${({ fadeRightColor }) => fadeRightColor || 'transparent'} 48px
    );
  }
  @media screen and (${BELOW_W_1024}) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    overflow: hidden;
  }
  @media screen and (${BELOW_W_768}) {
    display: block;
    &:after {
      border-left: none;
    }
  }
`;

const FeatureSpotlight = ({
  id,
  subtitle,
  title,
  body,
  image,
  rightColor,
  interfaceAnimation,
}: {
  id?: string;
  subtitle: string;
  title: string;
  body: ReactNode | string;
  image: ReactNode;
  rightColor: string;
  interfaceAnimation: ReactNode;
}) => {
  const positionWrapperRef = useRef<HTMLDivElement>(null);
  const sceneWrapperRef = useRef<HTMLDivElement>(null);
  const widthWrapperRef = useRef<HTMLDivElement>(null);
  useLayoutEffect(() => {
    const sceneWrapper = sceneWrapperRef.current;
    const positionWrapper = positionWrapperRef.current;
    if (!sceneWrapper || !positionWrapper) return;
    if (CSS.supports('animation-timeline: scroll(root)')) {
      const onResize = () => {
        setTimeout(() => {
          const bodyRect = document.body.getBoundingClientRect();
          const sceneWrapperRect = sceneWrapper.getBoundingClientRect();
          const positionWrapperRect = positionWrapper.getBoundingClientRect();
          const top = positionWrapperRect.top - bodyRect.top;
          const bottom = positionWrapperRect.top + sceneWrapperRect.height - bodyRect.top;
          sceneWrapper.setAttribute('style', `animation-range: ${top - 48}px ${bottom - 48}px;`);
        });
      };
      onResize();
      window.addEventListener('resize', onResize);
      return () => window.removeEventListener('resize', onResize);
    } else if (window.innerWidth >= 1024) {
      const widthWrapper = widthWrapperRef.current;
      if (!widthWrapper) return;
      const onScroll = () => {
        const positionWrapperRect = positionWrapper.getBoundingClientRect();
        const sceneWrapperRect = sceneWrapper.getBoundingClientRect();
        const widthWrapperRect = widthWrapper.getBoundingClientRect();
        const scrollAmount =
          1 -
          Math.max(
            0,
            Math.min(1, (positionWrapperRect.top + sceneWrapperRect.height - 48) / (window.innerHeight - 48))
          );

        if (scrollAmount <= 0) {
          sceneWrapper.setAttribute('style', `animation: none; transform: translateY(0);`);
        } else if (scrollAmount >= 1) {
          sceneWrapper.setAttribute('style', `animation: none; transform: translateY(100%);`);
        } else {
          sceneWrapper.setAttribute(
            'style',
            `animation: none; position: fixed; top: 48px; bottom: 0; width: ${widthWrapperRect.width}px;`
          );
        }
      };
      onScroll();
      window.addEventListener('scroll', onScroll);
      return () => window.removeEventListener('scroll', onScroll);
    }
  }, []);
  return (
    <ResponsiveContainer mobileBackgroundColor={rightColor} ref={positionWrapperRef}>
      <FeatureSpotlightWrapper id={id}>
        <VerticalBlock>
          <FeatureSpotlightColumns>
            <div ref={widthWrapperRef}>
              <PinnedPaddedBlock ref={sceneWrapperRef}>
                <div>
                  <Subtitle>{subtitle}</Subtitle>
                  <FeatureTitle>{title}</FeatureTitle>
                </div>
                <MobileAnimWrapper>{interfaceAnimation}</MobileAnimWrapper>
                <Body>{body}</Body>
              </PinnedPaddedBlock>
            </div>
            <StackWrapper fadeRightColor={rightColor}>
              <FullHeightVerticalBlock>
                <ImageContainer>{image}</ImageContainer>
              </FullHeightVerticalBlock>
              <FullHeightVerticalBlock>
                <DesktopAnimWrapper>{interfaceAnimation}</DesktopAnimWrapper>
              </FullHeightVerticalBlock>
            </StackWrapper>
          </FeatureSpotlightColumns>
        </VerticalBlock>
      </FeatureSpotlightWrapper>
    </ResponsiveContainer>
  );
};

export default FeatureSpotlight;
