import { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import { Layout } from "antd";
import ContentRenderer from "./ContentRenderer";
import HeaderLogo from "./HeaderLogo";
import ScrollIcon from "../icons/ScrollIcon";
import { useMediaQuery } from "react-responsive";
import ImageCarousel from "./ImageCarousel";
import CloseButton from "./CloseButton";
import MenuButton from "./MenuButton";
import { useSettingsContext } from "../contexts/SettingsContext";

const { Content } = Layout;

const Page = ({
  pageData,
  theme = null,
  visible = true,
  id = 0,
  showClose = false,
  isSubPage = false,
  showMenu = true,
  onClose = () => {},
}) => {
  const isLargeMobile = useMediaQuery({ maxWidth: 1200 });
  const isMobile = useMediaQuery({ maxWidth: 800 });
  const mobileImage =
    isMobile &&
    !pageData.showProperties &&
    !pageData.showContactForm &&
    !pageData.hideMobileImage;
  const contentRef = useRef(null);
  const [isImageShrunk, setIsImageShrunk] = useState(false);
  const [safariBlurToggle, setSafariBlurToggle] = useState(false);
  const shrinkDistance = 1;

  const settings = useSettingsContext();
  const themes = settings?.themes || [];

  if (theme == null) {
    theme = settings?.globalThemes?.page || settings?.themes[0];
  }

  // Reset scroll position and image state when visible becomes false
  useEffect(() => {
    if (!visible && contentRef.current) {
      contentRef.current.scrollTop = 0;
      setIsImageShrunk(false);
    }
  }, [visible]);

  // SafariBlurToggle animation when isImageShrunk changes
  useEffect(() => {
    if (!mobileImage) return;

    let animationId;
    let timeoutId;
    const startTime = Date.now();
    const duration = 750; // 0.75 seconds

    const animate = () => {
      const elapsed = Date.now() - startTime;

      if (elapsed < duration) {
        setSafariBlurToggle((prev) => !prev);
        animationId = requestAnimationFrame(animate);
      } else {
        // Stop toggling after 0.75s
        setSafariBlurToggle(false);
      }
    };

    // Start the animation
    animationId = requestAnimationFrame(animate);

    return () => {
      if (animationId) {
        cancelAnimationFrame(animationId);
      }
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
    };
  }, [isImageShrunk, mobileImage]);

  useEffect(() => {
    if (!contentRef.current || !mobileImage) return;

    const handleScroll = () => {
      // Don't shrink image if page is not visible
      if (!visible) return;

      const el = contentRef.current;
      const scrollTop = el.scrollTop;
      const scrollHeight = el.scrollHeight;
      const clientHeight = el.clientHeight;

      // Check if the container can be scrolled (is overflowing)
      const canScroll = scrollHeight > clientHeight;

      const shouldShrink = scrollTop > shrinkDistance;

      // If container can't be scrolled, keep image shrunk if it's already shrunk
      if (!canScroll && isImageShrunk) {
        return; // Keep the image shrunk
      }

      // If container can be scrolled, allow image to un-shrink when at top
      if (canScroll) {
        if (scrollTop <= shrinkDistance) {
          setIsImageShrunk(false);
        } else if (shouldShrink) {
          setIsImageShrunk(true);
        }
      } else if (shouldShrink) {
        // If container can't be scrolled but we're past threshold, shrink
        setIsImageShrunk(true);
      }
    };

    const el = contentRef.current;
    el.addEventListener("scroll", handleScroll);

    return () => {
      el.removeEventListener("scroll", handleScroll);
    };
  }, [mobileImage, visible, isImageShrunk]);

  return (
    <div
      className={
        !isMobile
          ? "th-page-container"
          : "th-page-container th-page-container-mobile"
      }
      style={{
        "--th-backgroundColor": theme?.backgroundColor,
        "--th-textColor": theme?.textColor,
        background: "var(--th-backgroundColor)",
      }}
    >
      <div
        className={`th-header${visible == false ? " th-header-hidden" : ""}${
          isLargeMobile ? " th-header-mobile" : ""
        }${mobileImage ? " th-header-float" : ""}`}
        style={{
          "--th-textColor":
            pageData?.invertHeader && isMobile
              ? theme?.backgroundColor
              : theme?.textColor,
        }}
      >
        <HeaderLogo
          themes={themes}
          currentTheme={pageData.theme}
          large={id === 0 && !isSubPage}
        />
        {showClose && <CloseButton onClick={onClose} />}
        {showMenu && id != 0 && !isSubPage && (
          <MenuButton isInverted={pageData.invertHeader && isMobile} />
        )}
      </div>
      {mobileImage && (
        <div
          className={`th-page-mobile-image-wrapper${
            visible == false ? ` th-page-mobile-image-wrapper-hidden` : ``
          }${isImageShrunk ? ` th-page-mobile-image-wrapper-shrunk` : ``}`}
        >
          <div
            className={`th-top-gradient ${safariBlurToggle ? "refresh" : ""}`}
          ></div>
          <ImageCarousel page={pageData} className="th-mobile-image" />
        </div>
      )}
      <Content
        className={`th-page-content${
          visible == false ? " th-page-content-hidden" : ""
        }${isLargeMobile ? " th-page-content-mobile" : ""}`}
        ref={contentRef}
      >
        <div className="th-content-container-wrapper">
          <div
            className={`th-content-container ${
              mobileImage ? " th-content-container-mobile-image" : ""
            }`}
          >
            <ContentRenderer content={pageData?.content} />
          </div>
        </div>
      </Content>
      {pageData?.showScroll == true && <ScrollIcon visible={visible} />}
    </div>
  );
};

Page.propTypes = {
  id: PropTypes.number,
  pageData: PropTypes.object,
  theme: PropTypes.shape({
    backgroundColor: PropTypes.any,
    textColor: PropTypes.any,
  }),
  isSubPage: PropTypes.bool,
  showClose: PropTypes.bool,
  showMenu: PropTypes.bool,
  themes: PropTypes.any,
  visible: PropTypes.bool,
  onClose: PropTypes.func,
};

export default Page;
