import Color from "colorjs.io";
import type { mastodon } from "masto";
import { createEffect, createMemo, Show } from "solid-js";
import { Title, Body1 } from "~material/typography";
import { averageColorHex } from "~platform/blurhash";
import "./PreviewCard.css";

function onResetImg(event: Event & { currentTarget: HTMLImageElement }) {
  event.currentTarget.classList.remove("loaded");
}

function onImgLoaded(event: Event & { currentTarget: HTMLImageElement }) {
  event.currentTarget.classList.add("loaded");
}

export function PreviewCard(props: {
  src: mastodon.v1.PreviewCard;
  alwaysCompact?: boolean;
}) {
  let root: HTMLAnchorElement;

  createEffect(() => {
    if (props.alwaysCompact) {
      root.classList.add("compact");
      return;
    }
    if (!props.src.width) return;
    const width = root.getBoundingClientRect().width;
    if (width > props.src.width) {
      root.classList.add("compact");
    } else {
      root.classList.remove("compact");
    }
  });

  const imgAverageColor = createMemo(() => {
    if (!props.src.image) return;
    return new Color(averageColorHex(props.src.blurhash));
  });

  const prefersWhiteText = createMemo(() => {
    const oc = imgAverageColor();
    if (!oc) return;
    const colorWhite = new Color("white");

    return colorWhite.luminance / oc.luminance > 3.5;
  });

  const focusSurfaceColor = createMemo(() => {
    const oc = imgAverageColor();
    if (!oc) return;
    if (prefersWhiteText()) {
      return new Color(oc).darken(0.2);
    } else {
      return new Color(oc).lighten(0.2);
    }
  });

  const textColorName = createMemo(() => {
    const useWhiteText = prefersWhiteText();
    if (typeof useWhiteText === "undefined") {
      return;
    }
    return useWhiteText ? "white" : "black";
  });

  const secondaryTextColor = createMemo(() => {
    const tcn = textColorName();
    if (!tcn) return;
    const tc = new Color(tcn);
    tc.alpha = 0.75;
    return tc;
  });

  return (
    <a
      ref={root!}
      class={"PreviewCard"}
      href={props.src.url}
      target="_blank"
      referrerPolicy="unsafe-url"
      style={{
        "--tutu-color-surface": imgAverageColor()?.toString(),
        "--tutu-color-surface-d": focusSurfaceColor()?.toString(),
        "--tutu-color-on-surface": textColorName(),
        "--tutu-color-secondary-text-on-surface":
          secondaryTextColor()?.toString(),
      }}
    >
      <Show when={props.src.image}>
        <img
          onLoadStart={onResetImg}
          onLoad={onImgLoaded}
          crossOrigin="anonymous"
          src={props.src.image!}
          width={props.src.width || undefined}
          height={props.src.height || undefined}
          loading="lazy"
        />
      </Show>
      <Title component="h1">{props.src.title}</Title>
      <Body1 component="p">{props.src.description}</Body1>
    </a>
  );
}

export default PreviewCard;
