import {
  CashIcon,
  ExpandCircleDownIcon,
  ExpandCircleUpIcon,
} from "@src/assets";
import { IconWithTooltip, Skeleton } from "@src/components";
import { useEffect, useMemo, useState } from "react";
import { YourCashItem } from "../YourCashItem";
import { abbreviateNumber } from "@src/utils";
import { EnrichedWalletToken } from "@src/models";
import { useSwapContext } from "@src/contexts";
import { motion, useMotionValue, useSpring, useTransform } from "framer-motion";

type Props = { yourCash: EnrichedWalletToken[]; isLoading: boolean };

export const YourCashExpandable = ({ yourCash, isLoading }: Props) => {
  const { isMultichain, balancesSnapshots } = useSwapContext();
  const [cashExpanded, setCashExpanded] = useState(false);

  const [enableScroll, setEnableScroll] = useState(false);
  const [isAnimating, setIsAnimating] = useState(false);

  useEffect(() => {
    if (!cashExpanded) setEnableScroll(false);
  }, [cashExpanded]);

  const currentTotalValue = useMemo(
    () => yourCash.reduce((sum, t) => sum + t.value, 0),
    [yourCash],
  );

  const previousTotalValue = Number(
    balancesSnapshots.totalCash?.initialValue ?? currentTotalValue,
  );

  const totalMv = useMotionValue(previousTotalValue);
  const totalSpring = useSpring(totalMv, { stiffness: 90, damping: 20 });

  useEffect(() => {
    if (currentTotalValue > previousTotalValue) {
      setIsAnimating(true);
      totalMv.set(previousTotalValue);

      requestAnimationFrame(() => {
        totalMv.set(currentTotalValue);
      });

      const unsubscribe = totalSpring.on("change", (latest) => {
        if (Math.abs(latest - currentTotalValue) < 0.01) {
          setIsAnimating(false);
          unsubscribe();
        }
      });
    }
  }, [currentTotalValue, previousTotalValue, totalMv, totalSpring]);

  const totalFormatted = useTransform(
    totalSpring,
    (latest) => `$${abbreviateNumber(latest, 2)}`,
  );

  useEffect(() => {
    totalMv.set(currentTotalValue);
  }, [currentTotalValue, totalMv]);

  const primary20 = useMemo(() => {
    const host = document.getElementById("swapper-sdk-root");
    const styleSource = host || document.documentElement;
    const hex = getComputedStyle(styleSource)
      .getPropertyValue("--swapper-primary-color")
      .trim();

    if (/^#[0-9A-Fa-f]{6}$/.test(hex)) {
      return `${hex}33`;
    }

    return hex;
  }, []);

  return (
    <motion.div
      initial={false}
      className="flex flex-col flex-0 p-4 rounded-xl"
      animate={{
        backgroundColor: isAnimating ? primary20 : "var(--swapper-card-bg)",
      }}
    >
      <div className="flex items-stretch justify-between w-full">
        <div className="flex gap-1 items-center">
          <CashIcon className="w-8 h-8" />
          <div className="flex gap-2 items-center">
            <p className="text-xl font-medium">Cash</p>
            <IconWithTooltip
              tooltipText="Cash balances are held in USDC, a fully collateralized stablecoin"
              id="onramp-fee-tooltip"
            />
          </div>
        </div>
        <div
          className={`flex gap-4 items-center ${
            isMultichain && "cursor-pointer"
          }`}
          onClick={() => {
            !isLoading && isMultichain && setCashExpanded((prev) => !prev);
          }}
        >
          {isLoading ? (
            <Skeleton className="w-10 h-3" />
          ) : (
            <motion.span className="font-bold text-xs">
              {totalFormatted}
            </motion.span>
          )}

          {isMultichain && (
            <div className={`${isLoading && "!cursor-wait opacity-50"}`}>
              {cashExpanded ? <ExpandCircleUpIcon /> : <ExpandCircleDownIcon />}
            </div>
          )}
        </div>
      </div>
      {yourCash && isMultichain && (
        <div
          onTransitionEnd={() => {
            if (cashExpanded) setEnableScroll(true);
          }}
          className={`flex flex-col gap-5 transition-[max-height] duration-300 overflow-hidden min-h-0 ${
            cashExpanded ? "max-h-[161px]" : "max-h-0"
          }`}
        >
          <div className="pt-3 flex flex-col gap-3 min-h-0">
            <div className="w-full h-[1px] bg-text_primary/10" />
            <div
              className={`flex flex-col gap-5 min-h-0 flex-1 ${
                enableScroll && cashExpanded
                  ? "overflow-y-auto"
                  : "overflow-hidden"
              }`}
            >
              {yourCash.map((t) => {
                return (
                  <YourCashItem
                    key={`${t.address}-${t.chainId}`}
                    balances={t.balances}
                    chainId={t.chainId}
                  />
                );
              })}
            </div>
          </div>
        </div>
      )}
    </motion.div>
  );
};
