import { Form, Formik } from "formik";
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import * as Yup from "yup";
import usersService from "../../../services/UsersService";
import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom";
import LoadingSpinner from "../../Spinners/LoadingSpinner";

const validationSchema = Yup.object().shape({
  cardNum: Yup.string()
    .min(6, "not a card number")
    .max(19, "16 chars max.") //16 chars + 3 spaces
    .test("luhn-validation", "Invalid Card Number", (value) => {
      const sanitizedNumber = value?.replace(/\D/g, "");
      const digits = Array?.from(sanitizedNumber, Number);

      for (let i = digits.length - 2; i >= 0; i -= 2) {
        digits[i] *= 2;
        if (digits[i] > 9) {
          digits[i] -= 9;
        }
      }

      const sum = digits.reduce((acc, digit) => acc + digit, 0);

      return sum % 10 === 0;
    })
    .required("required"),
  code: Yup.string()
    .min(3, "3 chars min.")
    .max(25, "25 chars max.")
    .required("required"),
  state: Yup.string()
    .min(3, "3 chars min.")
    .max(25, "25 chars max.")
    .required("required"),
  address: Yup.string()
    .min(3, "3 chars min.")
    .max(50, "50 chars max.")
    .required("required"),
  expirationYear: Yup.string()
    .min(4, "4 chars min.")
    .max(4, "4 chars max.")
    .required("required"),
  expirationMonth: Yup.string()
    .min(1, "1 chars min.")
    .max(2, "2 chars max.")
    .required("required"),
  cvv: Yup.string()
    .min(3, "3 chars min.")
    .max(4, "4 chars max.")
    .required("required"),
});

const initialValues = {
  cardNum: "",
  code: "",
  state: "",
  address: "",
  expirationYear: "",
  expirationMonth: "",
  cvv: "",
};

function AddFundDollars(props) {
  const apiCall = new usersService();
  let countryWallet = props.walletItem.country;
  const [tab, setTab] = useState("previous");
  const { userDetails } = useSelector((state) => state?.userDetails);
  const [prevCardDetails, setPrevCardDetails] = useState({});
  const [payListCards, setPayListCards] = useState({ loading: true, data: [] });
  const [cardIcons, setCardIcons] = useState("atm-card");

  const { firstname, lastname } = userDetails;

  // Handling Card Icons
  const handleCards = (event) => {
    const { name, value } = event.target;

    if (name == "cardNum") {
      // Check if the first character is 4 or 5 and set the card icon accordingly
      const cardIcon =
        value.length > 0
          ? value[0] === "4"
            ? "visa-card"
            : value[0] === "5"
            ? "master-card"
            : "atm-card"
          : "atm-card";
      setCardIcons(cardIcon);
    }
  };

  // Handling card change
  const handleInputChange = (event) => {
    const { name, value } = event.target;

    setPrevCardDetails((prevState) => ({
      ...prevState,
      [name]: value,
    }));
  };

  // Handling card number grouping
  const handleCardNumberChange = (value) => {
    return value
      ?.replace(/\s/g, "") // Remove existing spaces
      .match(/.{1,4}/g) // Group every four characters
      ?.join(" ");
  };

  // card slicer
  const indexOfFirstItem = 0;
  const indexOfLastItem =
    indexOfFirstItem + Number(process.env.REACT_APP_ITEM_PER_PAGE);
  const currentPreviousCards = payListCards?.data?.slice(
    indexOfFirstItem,
    indexOfLastItem
  );

  // Submission for both prev and new cards
  const handleSubmit = async (values, helpers) => {
    props.setInputError("");

    if (!props.input || props.input === "0") {
      props.setInputError("Please Enter Amount");
      setTimeout(() => props.setInputError(""), 5000);
      return;
    }

    if (isNaN(props.input)) {
      props.setInputError("Amount must be a Number");
      setTimeout(() => props.setInputError(""), 5000);
      return;
    }

    if (tab === "previous") {
      // To check if card is empty
      if (Object.keys(prevCardDetails).length === 0) {
        return;
      }
    }

    props.setConfirmCredit((prev) => ({
      ...prev,
      show: { awaitConfirm: { loader: true } },
    }));

    let stateData = {
      amount: Number(props.input) * 100,
      currency: props.walletItem?.code,
    };

    try {
      const res = await apiCall.getStartCredit(stateData);
      if (res.data.internal_return < 0) {
        props.setInputError("An Error Occurred");
        throw new Error("An Error Occurred");
      }

      const _response = res.data;
      stateData.amount = Number(props.input);
      stateData.card =
        tab === "previous" ? prevCardDetails["payment-card"] : { ...values };
      stateData.cardType = tab === "previous" ? "prev" : "new";
      stateData = { ...stateData, ..._response };

      setTimeout(() => {
        props.setConfirmCredit({
          show: {
            awaitConfirm: { loader: false, state: true },
            acceptConfirm: { loader: false, state: false },
          },
          data: stateData,
        });
      }, 1500);
    } catch (error) {
      props.setInputError(error.message);
      setTimeout(() => props.setInputError(""), 5000);
      props.setConfirmCredit((prev) => ({
        ...prev,
        show: { awaitConfirm: { loader: false } },
      }));
      console.log(error);
    }
  };

  useEffect(() => {
    apiCall
      .payListCard()
      .then((res) => {
        setPayListCards({ loading: false, data: res.data.result_list });
      })
      .catch((err) => {
        console.log("PAYCARDLIST ERROR", err);
        setPayListCards({ loading: false, data: [] });
      });
  }, []);

  const handleClose = props.onClose;

  return (
    <>
      <div className="w-full">
        {/* switch button */}
        <div className="flex">
          <form className="add-fund-info flex items-center gap-3">
            <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
              {countryWallet == "US" && "Payment Method"}
            </h1>
            <div className="my-1 flex items-center gap-2">
              <label
                onClick={() => setTab("previous")}
                htmlFor="previous"
                className="cursor-pointer flex items-center gap-1"
              >
                <input
                  type="radio"
                  id="previous"
                  name="card-option"
                  checked={tab === "previous"}
                  className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
                    tab == "previous" ? "" : ""
                  } tracking-wide transition duration-200`}
                />
                Previous Cards
              </label>
              <label
                onClick={() => setTab("new")}
                htmlFor="new"
                className="cursor-pointer flex items-center gap-1"
              >
                <input
                  id="new"
                  type="radio"
                  name="card-option"
                  checked={tab === "new"}
                  className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
                    tab == "new" ? "" : ""
                  }  tracking-wide transition duration-200`}
                />
                Add New Card
              </label>
            </div>
          </form>
        </div>
        <hr />
        {/* END OF switch button */}

        {/* previous tab */}
        {tab === "previous" && (
          <div className="p-4 previous-details w-full min-h-[16rem] flex flex-col justify-between items-center">
            {payListCards.loading ? (
              <LoadingSpinner size="10" color="sky-blue" />
            ) : payListCards?.data?.length ? (
              <select
                className="my-3 w-full rounded-full p-2 outline-none text-base text-black dark:text-gray-100 bg-[#FAFAFA] dark:bg-[#11131F] border"
                value={prevCardDetails["payment-card"]?.card_uid}
                id="payment-card"
                name="payment-card"
                onChange={handleInputChange}
              >
                <option value="">Select a card</option>
                {currentPreviousCards.map((item, index) => (
                  <option
                    key={index}
                    className={index !== 0 && "border-t-2"}
                    value={JSON.stringify(item)}
                  >
                    <div className="my-2 flex items-center gap-5">
                      <div className="card-details">
                        <h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
                          {item.description} Card
                        </h1>
                        <p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
                          Bank **************{item.digits}
                        </p>
                      </div>
                    </div>
                  </option>
                ))}
              </select>
            ) : (
              <div className="w-full flex flex-col items-center">
                <p className="my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide">
                  No Previous Card Found!
                </p>
                <button
                  onClick={() => setTab("new")}
                  type="button"
                  className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
                >
                  <span className="text-white">Add Card</span>
                </button>
              </div>
            )}
          </div>
        )}

        {tab === "new" && (
          <div className="new-details w-full max-h-[23rem]">
            <div className="w-full flex flex-col justify-between">
              <Formik
                initialValues={initialValues}
                validationSchema={validationSchema}
                onSubmit={handleSubmit}
              >
                {(props) => {
                  return (
                    <Form className="md:pl-8">
                      <div className="flex flex-col-reverse sm:flex-row">
                        <div className="flex-1 sm:mr-10">
                          <div className="fields w-full">
                            {/* Inputs */}
                            {/* Name */}
                            <div className="flex items-center field w-full my-2 flex-[0.4] gap-3">
                              <label className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1">
                                Name:
                              </label>
                              <p className="input-label text-[#181c32] dark:text-white text-[16px] leading-[20.9625px] font-semibold flex items-center gap-1">{`${firstname} ${lastname}`}</p>
                            </div>

                            <div className="flex items-center flex-1 gap-3 my-2">
                              {/* Card Number */}
                              <div className="field w-full flex-[0.6]">
                                <InputCom
                                  fieldClass="px-6"
                                  spanTag="*"
                                  iconName={cardIcons}
                                  label="Card Number"
                                  type="text"
                                  name="cardNum"
                                  onInput={handleCards}
                                  placeholder="Enter Card Number"
                                  value={handleCardNumberChange(
                                    props.values.cardNum
                                  )}
                                  inputHandler={props.handleChange}
                                  blurHandler={props.handleBlur}
                                  error={props.errors.cardNum}
                                />
                              </div>

                              {/* Expire Year, Year */}
                              <div className="sm:grid gap-5 grid-cols-2 flex-[0.4]">
                                <div className="field w-full mb-6 xl:mb-0 col-span-1">
                                  <div className="select-option">
                                    <div
                                      className={`flex items-center justify-between mb-2.5`}
                                    >
                                      <label
                                        className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold line-clamp-3 flex items-center"
                                        htmlFor="expiration"
                                      >
                                        Exp Month{" "}
                                        <span className="text-red-700 text-sm italic">
                                          *
                                        </span>
                                        <span className="text-[12px] text-red-500 ml-1">
                                          {props.errors.expirationMonth && "**"}
                                        </span>
                                      </label>
                                    </div>
                                    <div
                                      className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
                                    >
                                      <select
                                        className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
                                        value={props.values.expirationMonth}
                                        onChange={props.handleChange}
                                        onBlur={props.handleBlur}
                                        name="expirationMonth"
                                      >
                                        <option
                                          value=""
                                          className="text-dark-gray"
                                        >
                                          Month
                                        </option>
                                        {expireMonth?.length &&
                                          expireMonth.map((item, index) => (
                                            <option
                                              key={index}
                                              value={item.value}
                                            >
                                              {item.name}
                                            </option>
                                          ))}
                                      </select>
                                    </div>
                                  </div>
                                </div>

                                <div className="field w-full mb-6 xl:mb-0 col-span-1">
                                  <div className="select-option">
                                    <div
                                      className={`flex items-center justify-between mb-2.5`}
                                    >
                                      <label
                                        className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center line-clamp-3"
                                        htmlFor="expiration"
                                      >
                                        Exp Year{" "}
                                        <span className="text-red-700 text-sm tracking-wide">
                                          *
                                        </span>
                                        <span className="text-[12px] text-red-500 italic">
                                          {props.errors.expirationYear && "**"}
                                        </span>
                                      </label>
                                    </div>
                                    <div
                                      className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
                                    >
                                      <select
                                        className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
                                        value={props.values.expirationYear}
                                        onChange={props.handleChange}
                                        onBlur={props.handleBlur}
                                        name="expirationYear"
                                      >
                                        <option
                                          value=""
                                          className="text-dark-gray"
                                        >
                                          Year
                                        </option>
                                        {expireYear?.length &&
                                          expireYear.map((item, index) => (
                                            <option key={index} value={item}>
                                              {item}
                                            </option>
                                          ))}
                                      </select>
                                    </div>
                                  </div>
                                </div>
                              </div>
                            </div>

                            {/* Address and CVV */}
                            <div className="flex items-center flex-1 gap-3 my-2">
                              <div className="field w-full col-span-1 flex-[0.4]">
                                <InputCom
                                  fieldClass="px-6"
                                  spanTag="*"
                                  iconName={cardIcons}
                                  label="CVV"
                                  type="number"
                                  name="cvv"
                                  placeholder="CVV"
                                  maxLength={3}
                                  value={props.values.cvv}
                                  inputHandler={props.handleChange}
                                  blurHandler={props.handleBlur}
                                  error={props.errors.cvv}
                                />
                              </div>
                              <div className="field w-full flex-[0.6]">
                                <InputCom
                                  fieldClass="px-6"
                                  spanTag="*"
                                  label="Billing Address"
                                  type="text"
                                  name="address"
                                  placeholder="Billing Address"
                                  value={props.values.Address}
                                  inputHandler={props.handleChange}
                                  blurHandler={props.handleBlur}
                                  error={props.errors.address}
                                />
                              </div>
                            </div>

                            {/* Postal Code and State */}
                            <div className="sm:grid gap-5 grid-cols-3 my-2">
                              <div className="field w-full mb-6 xl:mb-0 col-span-1">
                                <InputCom
                                  fieldClass="px-6"
                                  spanTag="*"
                                  label="Postal Code"
                                  type="text"
                                  name="code"
                                  placeholder="Postal Code"
                                  value={props.values.code}
                                  maxLength={6}
                                  inputHandler={props.handleChange}
                                  blurHandler={props.handleBlur}
                                  error={props.errors.code}
                                />
                              </div>
                              <div className="field w-full col-span-1">
                                <InputCom
                                  fieldClass="px-6"
                                  spanTag="*"
                                  label="State"
                                  type="text"
                                  name="state"
                                  placeholder="State"
                                  value={props.values.state}
                                  inputHandler={props.handleChange}
                                  blurHandler={props.handleBlur}
                                  error={props.errors.state}
                                />
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>

                      <div className="md:px-8 md:pt-4 px-4 pt-2 add-fund-btn flex justify-end items-center gap-3">
                        <button
                          className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
                          onClick={handleClose}
                        >
                          Cancel
                        </button>
                        <button
                          type="submit"
                          className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
                        >
                          {props.confirmCredit?.show?.awaitConfirm?.loader ? (
                            <LoadingSpinner size="6" color="sky-blue" />
                          ) : (
                            <>
                              <span className="text-white">Continue</span>{" "}
                              <Icons name="chevron-right" />
                            </>
                          )}
                        </button>
                      </div>
                    </Form>
                  );
                }}
              </Formik>
            </div>
          </div>
        )}
      </div>

      {tab == "previous" && (
        <div className="md:py-8 px-[38px] add-fund-btn flex justify-end items-center gap-4 py-4">
          <button
            className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
            onClick={props.onClose}
          >
            Cancel
          </button>
          <button
            onClick={handleSubmit}
            name="previous"
            type="button"
            className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
          >
            {props.confirmCredit?.show?.awaitConfirm?.loader ? (
              <LoadingSpinner size="6" color="sky-blue" />
            ) : (
              <span className="text-white">Continue</span>
            )}
          </button>
        </div>
      )}
    </>
  );
}

export default AddFundDollars;

// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
const expireYear = [];
let currentYear = new Date().getFullYear();
for (let i = 0; i <= 6; i++) {
  expireYear.push(currentYear + i);
}

// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
let month = [
  "January",
  "February",
  "March",
  "April",
  "May",
  "June",
  "July",
  "August",
  "September",
  "October",
  "November",
  "December",
];
const expireMonth = [];
for (let i = 0; i < month.length; i++) {
  expireMonth.push({ name: month[i], value: i + 1 });
}
