import React, { useEffect, useState } from "react";
import clsx from "clsx";

const rotationDuration = 3800;
const bezier = "cubic-bezier(0.645,0.045,0.355,1)";

function Coin(props: {
  frontList: boolean[];
  rotation: boolean;
  onTransitionEnd: () => void;
}) {
  const [lastFront, setLastFront] = useState(props.frontList);

  useEffect(() => {
    if (!props.rotation) {
      return;
    }

    const id = setTimeout(() => {
      setLastFront(props.frontList);
      props.onTransitionEnd();
    }, rotationDuration);
    return () => clearTimeout(id);
  }, [props.rotation, props.frontList, props.onTransitionEnd]);

  return (
    <div className="flex w-full max-w-md justify-around rounded-md border bg-secondary p-4 shadow dark:border-0 dark:shadow-none sm:p-6">
      {props.frontList.map((value, index) => (
        <CoinItem
          key={index}
          front={value}
          lastFront={lastFront[index]}
          rotation={props.rotation}
        />
      ))}
    </div>
  );
}

function CoinFace({ side }: { side: "front" | "back" }) {
  const isFront = side === "front";
  return (
    <div
      className={clsx(
        "absolute inset-0 flex items-center justify-center rounded-full border-[3px] shadow-inner",
        isFront
          ? "border-amber-500 bg-gradient-to-br from-amber-200 to-amber-400 text-amber-950"
          : "border-stone-500 bg-gradient-to-br from-stone-300 to-stone-500 text-stone-800",
      )}
      style={{
        backfaceVisibility: "hidden",
        transform: isFront ? undefined : "rotateY(180deg)",
      }}
    >
      <span className="select-none text-lg font-bold sm:text-xl">
        {isFront ? "正" : "反"}
      </span>
    </div>
  );
}

function CoinItem(props: {
  front: boolean;
  lastFront: boolean;
  rotation: boolean;
}) {
  let animate = "";
  if (props.rotation) {
    animate = `animate-[coin-${getFront(props.lastFront)}-${getFront(
      props.front,
    )}_${rotationDuration / 1000}s_${bezier}]`;
  }

  return (
    <div
      className="h-16 w-16 sm:h-20 sm:w-20"
      style={{ perspective: "800px" }}
    >
      <div
        style={{
          transform: `rotateY(${props.front ? 0 : 180}deg)`,
          transformStyle: "preserve-3d",
        }}
        className={clsx("relative h-full w-full", animate)}
      >
        <CoinFace side="front" />
        <CoinFace side="back" />
      </div>
    </div>
  );
}

function getFront(front: boolean): string {
  return front ? "front" : "back";
}

export default Coin;
