import {
  CheckIcon,
  SignIcon,
  ThumbUpRoundedIcon,
  WaitingIcon,
} from "@src/assets/icons";
import { useTxUIWrapper } from "@src/context";
import { TxStatus } from "@src/models";
import { ReactElement, useMemo } from "react";

type Step = {
  icon: (className: string) => ReactElement;
  title: string;
  state: "none" | "triggered" | "completed";
  show: boolean;
};

// TODO item's 'show' logic is a bit complicated/weird. Think about an improvement...
export const Steps = () => {
  const { txStatus, txNeedsApproval, txMsg } = useTxUIWrapper();

  const items: Step[] = useMemo(
    () => [
      {
        icon: (className) => (
          <div className={`${className}`}>
            <SignIcon />
          </div>
        ),
        title: "sign approval transaction",
        state:
          txStatus === TxStatus.SIGNING_APPROVAL
            ? "triggered"
            : txStatus > TxStatus.SIGNING_APPROVAL
            ? "completed"
            : "none",
        show: txMsg
          ? txStatus === TxStatus.SIGNING_APPROVAL ||
            txStatus === TxStatus.CONFIRMING_APPROVAL
          : txNeedsApproval,
      },
      {
        icon: (className) => (
          <div className={`${className}`}>
            <ThumbUpRoundedIcon />
          </div>
        ),
        title: "confirming approval transaction...",
        state:
          txStatus === TxStatus.CONFIRMING_APPROVAL
            ? "triggered"
            : txStatus > TxStatus.CONFIRMING_APPROVAL
            ? "completed"
            : "none",
        show: txMsg
          ? txStatus === TxStatus.SIGNING_APPROVAL ||
            txStatus === TxStatus.CONFIRMING_APPROVAL
          : txNeedsApproval,
      },
      {
        icon: (className) => (
          <div className={`${className}`}>
            <SignIcon />
          </div>
        ),
        title: "sign transaction",
        state:
          txStatus === TxStatus.SIGNING_TX
            ? "triggered"
            : txStatus > TxStatus.SIGNING_TX
            ? "completed"
            : "none",
        show: txMsg
          ? txStatus === TxStatus.SIGNING_TX ||
            txStatus === TxStatus.CONFIRMING_TX
          : true,
      },
      {
        icon: (className) => (
          <div className={`${className}`}>
            <ThumbUpRoundedIcon />
          </div>
        ),
        title: "confirming transaction...",
        state:
          txStatus === TxStatus.CONFIRMING_TX
            ? "triggered"
            : txStatus > TxStatus.CONFIRMING_TX
            ? "completed"
            : "none",
        show: txMsg
          ? txStatus === TxStatus.SIGNING_TX ||
            txStatus === TxStatus.CONFIRMING_TX
          : true,
      },
    ],
    [txMsg, txNeedsApproval, txStatus],
  );

  const filteredItems = useMemo(
    () => items.filter(({ show }) => show),
    [items],
  );

  return (
    <div className="flex flex-col gap-1">
      {filteredItems.map(({ icon, title, state }, index) => (
        <div key={title} className="flex flex-col px-4 gap-1">
          <div className="flex justify-between items-center">
            <div className="flex items-center gap-2">
              {icon(
                `${
                  state === "triggered"
                    ? "fill-t_main_accent_light"
                    : "fill-t_text_primary opacity-50"
                }`,
              )}
              <div
                className={`${
                  state !== "triggered"
                    ? "opacity-50"
                    : state === "triggered" && "text-t_text_secondary"
                }`}
              >
                {title}
              </div>
            </div>
            <div>
              {state === "completed" ? (
                <div className="fill-t_success_dark">
                  <CheckIcon />
                </div>
              ) : state === "triggered" ? (
                <div className="animate-spin-slow fill-t_main_accent_light">
                  <WaitingIcon />
                </div>
              ) : null}
            </div>
          </div>
          {index !== filteredItems.length - 1 && (
            <div className="vertical-separator py-3 ml-2" />
          )}
        </div>
      ))}
    </div>
  );
};
