import {
  Button,
  Menu,
  MenuHandler,
  MenuItem,
  MenuList,
  Slider,
  Typography,
} from "@material-tailwind/react";
import React, { Dispatch, useEffect, useMemo, useState } from "react";
import { GoChevronDown } from "react-icons/go";
import { HiOutlineArrowSmLeft } from "react-icons/hi";

import { ROUTES } from "../../constants/routes";
import { useGlobalDebounce } from "../../hooks/useDebounce";
import { _useScopedI18n } from "../../i18n/client";
import { Asset, Commission, Option } from "../../types/payments";
import ButtonCustom from "../Button";
import CustomNextLink from "../CustomNextLink";

// Payment method update function type
type PaymentUpdateFunction = (params: any) => Promise<void> | void;

// Configuration for different cart types
interface CartConfig {
  updatePaymentMethod: PaymentUpdateFunction;
  showCommissions?: boolean;
  additionalParams?: Record<string, any>;
}

type WalletSliderComponentProps = {
  asset: Asset;
  selectedOption: Option;
  grandTotal: number;
  baseAmountToPay: number;
  optionAmountToPay: number;
  commission: Commission;
  setSelectedAsset: Dispatch<any>;
  setSelectedOption: (option: Option) => void;
  cartConfig: CartConfig;
};

export default function WalletSliderComponent({
  asset,
  selectedOption,
  grandTotal,
  baseAmountToPay,
  optionAmountToPay,
  commission,
  setSelectedAsset,
  setSelectedOption,
  cartConfig,
}: WalletSliderComponentProps) {
  const scopeT = _useScopedI18n("payment.walletSliderComponent");

  const [openMenu, setOpenMenu] = useState(false);
  const [currentPercentage, setCurrentPercentage] = useState<number>(
    selectedOption.currentPercentage ?? selectedOption.minPercentage,
  );

  const {
    updatePaymentMethod,
    showCommissions = true,
    additionalParams = {},
  } = cartConfig;

  const handleChangePercentage = useGlobalDebounce(
    async (percentage: number) => {
      const params = {
        paymentMethodId: asset.paymentMethodId,
        paymentOptionId: selectedOption.id,
        fromAssetSelectedPercentage: percentage,
        ...additionalParams,
      };

      await updatePaymentMethod(params);
    },
    300,
  );

  const handleSliderChange = (e: any) => {
    let value = +e.target.value;

    if (value < selectedOption.minPercentage) {
      value = selectedOption.minPercentage;
    } else if (value > 99) {
      value = 99;
    }

    setCurrentPercentage(value);

    if (selectedOption.currentPercentage == value) return;
    handleChangePercentage(value);
  };

  useEffect(() => {
    (async () =>
      await setCurrentPercentage(
        selectedOption.currentPercentage ?? selectedOption.minPercentage,
      ))();
  }, [selectedOption, setCurrentPercentage]);

  const canPayWithBase = useMemo(() => {
    if (+asset.balance < baseAmountToPay) return false;
    return true;
  }, [asset, baseAmountToPay]);

  const canPayWithOption = useMemo(() => {
    if (+selectedOption.balance < optionAmountToPay) return false;
    return true;
  }, [selectedOption, optionAmountToPay]);

  return (
    <>
      <div className="">
        <ButtonCustom
          variant="text"
          className="text-base mb-2 p-0"
          icon={undefined}
          onClick={() => {
            setSelectedAsset(null);
          }}
        >
          <HiOutlineArrowSmLeft className="text-2xl" />
          {scopeT("backBtn")}
        </ButtonCustom>

        <div className="overflow-x-auto">
          <div className="flex flex-col md:flex-row md:min-w-[600px] justify-between items-center gap-5 py-4">
            <div
              className={`flex flex-col justify-center items-center border ${canPayWithBase ? "border-slate-100" : "text-orange-500 bg-orange-50 border-orange-300"} rounded-xl p-4 min-w-30`}
            >
              <Typography
                variant="lead"
                className="text-sm font-semibold text-black-500 p-1"
              >
                {asset.name}
              </Typography>
              <Typography
                variant="lead"
                className="text-xs font-semibold text-gray-300 my-2"
              >
                {scopeT("amount")} : {baseAmountToPay}
              </Typography>
              {showCommissions && selectedOption.commissions?.base && (
                <Typography
                  variant="lead"
                  className="text-xs font-medium text-slate-500"
                >
                  CV: {selectedOption.commissions.base.cv} VP:{" "}
                  {selectedOption.commissions.base.vp}
                </Typography>
              )}
            </div>

            <div className="flex flex-1 flex-col items-center gap-5">
              <div className="flex items-center gap-3 w-full">
                <Typography
                  variant="lead"
                  className="text-sm font-normal text-black-500"
                >
                  {currentPercentage}%
                </Typography>
                <Slider
                  key={selectedOption.id}
                  onChange={handleSliderChange}
                  min={0}
                  value={currentPercentage}
                  max={100}
                  step={1}
                  color="green"
                  className="flex-1 my-4 md:my-0"
                />

                <Typography
                  variant="lead"
                  className="text-sm font-normal text-black-500"
                >
                  {100 - currentPercentage}%
                </Typography>
              </div>
            </div>

            <div
              className={`flex flex-col justify-center items-center border ${canPayWithOption ? "border-slate-100" : "text-orange-500 bg-orange-50 border-orange-300"} rounded-xl p-4 min-w-30`}
            >
              <Menu open={openMenu} handler={setOpenMenu}>
                <MenuHandler>
                  <Button
                    variant="text"
                    size="sm"
                    className="flex justify-center items-center gap-1 p-1 text-sm font-semibold text-black-500 "
                  >
                    {selectedOption.name}
                    <GoChevronDown
                      strokeWidth={2.5}
                      className={`h-3.5 w-3.5 transition-transform ${
                        openMenu ? "rotate-180" : ""
                      }`}
                    />
                  </Button>
                </MenuHandler>
                <MenuList className="p-1">
                  {asset.options.map((option, index) => {
                    let isEligible = false;

                    if (
                      +option.balance > 0 &&
                      option.restricted.status === false
                    ) {
                      isEligible = true;
                    }

                    return (
                      <MenuItem
                        onClick={() => {
                          isEligible && setSelectedOption(option);
                        }}
                        key={index}
                        className=""
                        disabled={
                          !isEligible || selectedOption.id === option.id
                        }
                      >
                        <div className="flex">
                          <div>
                            <Typography
                              variant="h6"
                              className="text-sm font-semibold text-black-500"
                            >
                              {option.name}
                            </Typography>
                            <Typography
                              variant="lead"
                              className="text-xs font-semibold text-gray-400"
                            >
                              {scopeT("avlBalance")}: {option.balance}
                            </Typography>
                          </div>
                        </div>
                      </MenuItem>
                    );
                  })}{" "}
                </MenuList>
              </Menu>
              <Typography
                variant="lead"
                className="text-xs font-semibold text-gray-300 my-2"
              >
                {scopeT("amount")} : {optionAmountToPay}
              </Typography>
              {showCommissions && selectedOption.commissions?.option && (
                <Typography
                  variant="lead"
                  className="text-xs font-medium text-slate-500"
                >
                  CV: {selectedOption.commissions.option.cv} VP:{" "}
                  {selectedOption.commissions.option.vp}
                </Typography>
              )}
            </div>
          </div>
        </div>
        <div className="text-center mt-4">
          <Typography
            variant="lead"
            className="text-base font-normal text-black-500"
          >
            {scopeT("grandTotal")}: <strong> $ {grandTotal} </strong>
          </Typography>
        </div>

        {showCommissions && (
          <div className="text-center mt-3">
            <Typography
              variant="lead"
              className="text-sm font-normal text-black-500"
            >
              CV: <strong>{commission?.totalCV}</strong> VP:{" "}
              <strong>{commission?.totalVP}</strong>
            </Typography>
          </div>
        )}

        <div className="w-[70%] mx-auto grid grid-cols-1 md:grid-cols-2 gap-5 mt-6">
          {+selectedOption.balance < optionAmountToPay && (
            <div className="flex flex-col justify-between text-center text-orange-500 bg-orange-50 border border-orange-300 px-3 py-4 rounded-lg">
              <Typography
                variant="lead"
                className="text-xs text-center leading-5 font-medium break-words"
              >
                {scopeT("insufficientBalance")} <br />
                {selectedOption.name}: {selectedOption.balance} <br />
              </Typography>
              <CustomNextLink
                target="_blank"
                className="underline font-semibold text-sm mt-3 block text-purple-500 hover:text-purple-600"
                href={ROUTES.dashboard.nodeLinkDeposit}
              >
                {scopeT("depositBtn")}
              </CustomNextLink>
            </div>
          )}

          {+asset.balance < baseAmountToPay && (
            <div className="flex flex-col justify-between text-center text-orange-500 bg-orange-50 border border-orange-300 px-3 py-4 rounded-lg">
              <Typography
                variant="lead"
                className="text-xs text-center leading-5 font-medium break-words"
              >
                {scopeT("insufficientBalance")} <br />
                {asset.name}: {asset.balance} <br />
              </Typography>
              <CustomNextLink
                target="_blank"
                className="underline font-semibold text-sm mt-3 block text-purple-500 hover:text-purple-600"
                href={ROUTES.dashboard.nodeLinkDeposit}
              >
                {scopeT("depositBtn")}
              </CustomNextLink>
            </div>
          )}
        </div>
      </div>
    </>
  );
}
