import clsx from "clsx";
import { ReactNode, useEffect, useRef } from "react";

interface IProps {
  layout?: "legacy" | "phone";
  className?: string;
  children: ReactNode;
}

const defaultThumbSize = 180;

export function CardList({ layout = "legacy", className, children }: IProps) {
  const cardListRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (layout === "phone") {
      return;
    }

    const ref = cardListRef.current;

    if (!ref) {
      return;
    }

    try {
      const cookies = getCookies();
      const thumbSizeValue = parseInt(cookies?.thumbSize);
      let thumbSizeSetting = isNaN(thumbSizeValue) ? undefined : thumbSizeValue;

      if (!thumbSizeSetting) {
        thumbSizeSetting = defaultThumbSize;
        addCookie("thumbSize", String(defaultThumbSize), 399);
      }

      const thumbSize =
        parseInt(String(thumbSizeSetting)) ===
        parseInt(String(defaultThumbSize))
          ? undefined
          : thumbSizeSetting;

      function handleResize() {
        updateThumbsizes(ref!, defaultThumbSize, thumbSize);
      }

      updateThumbsizes(ref!, defaultThumbSize, thumbSize);
      window.addEventListener("resize", handleResize);

      return () => {
        window.removeEventListener("resize", handleResize);
      };
    } catch (error) {
      return console.error(error);
    }
  }, []);

  return (
    <div className={clsx("card-list", `card-list--${layout}`, className)}>
      <div className="card-list__layout"></div>
      <div ref={cardListRef} className="card-list__items">
        {children}
      </div>
    </div>
  );
}

function getCookies(): Record<string, string> {
  const cookies = document.cookie.split(";").reduce(
    (cookies, cookie) => (
      // @ts-expect-error whatever
      (cookies[cookie.split("=")[0].trim()] = decodeURIComponent(
        cookie.split("=")[1]
      )),
      cookies
    ),
    {}
  );

  return cookies;
}

function setCookie(name: "thumbSize", value: string, daysToExpire: number) {
  const date = new Date();
  date.setTime(date.getTime() + daysToExpire * 24 * 60 * 60 * 1000);
  const expires = "expires=" + date.toUTCString();
  document.cookie = name + "=" + value + "; " + expires + ";path=/";
}

function addCookie(name: "thumbSize", newValue: string, daysToExpire: number) {
  const existingCookie = document.cookie
    .split(";")
    .find((cookie) => cookie.trim().startsWith(name + "="));

  if (!existingCookie) {
    setCookie(name, newValue, daysToExpire);
  }
}

/**
 * TODO: move into card component
 */
function updateThumbsizes(
  element: HTMLDivElement,
  defaultSize: number,
  thumbSizeSetting?: number
) {
  let thumbSize = thumbSizeSetting ? thumbSizeSetting : defaultSize;

  if (!thumbSizeSetting) {
    let viewportWidth = window.innerWidth;
    let offset = 24;
    let viewportWidthExcludingMargin = viewportWidth - offset;
    let howManyFit = viewportWidthExcludingMargin / thumbSize;

    if (howManyFit < 2.0 && 1.5 < howManyFit) {
      thumbSize = viewportWidthExcludingMargin / 2;
    } else if (howManyFit > 12) {
      thumbSize = defaultSize * 1.5;
    }
  }
  element.style.setProperty("--card-size", `${thumbSize}px`);
}
