import React, { useEffect } from "react";
import { Link, NavLink } from "react-router-dom";
import { PiUsersThreeFill } from "react-icons/pi";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import MkdSDK from "Utils/MkdSDK";
import { MdDashboard } from "react-icons/md";
import {
  GlobalContext,
  RequestItems,
  createRequest,
  customRequest,
  deleteRequest,
  getSingleModel,
  showToast,
  updateRequest,
} from "Context/Global";
import { AuthContext, tokenExpireError } from "Src/authContext";
import { MkdInput } from "Components/MkdInput";
import { InteractiveButton } from "Components/InteractiveButton";
import { SkeletonLoader } from "Components/Skeleton";
import { StringCaser, getNonNullValue } from "Utils/utils";
import AddButton from "Components/AddButton";

export const ActionConfirmation = ({
  data = { id: null },
  options = { endpoint: null, method: "GET" },
  onSuccess,
  onClose,
  multiple = false,
  action = "",
  mode = "create",
  customMessage = "",
  table = "",
  input = "input",
  initialValue = "",
  inputType = "text",
  disableCancel = false,
  inputConfirmation = true,
}) => {
  let sdk = new MkdSDK();

  const schema = yup
    .object({
      ...(["input", "input_create", "input_update"].includes(mode)
        ? {
            [input]: yup.string().required(),
          }
        : {
            confirm: yup
              .string()
              .required()
              .oneOf([action], `Confirmation must be "${action}"`),
          }),
    })
    .required();

  const {
    state: { createModel, updateModel, deleteModel },
    dispatch: globalDispatch,
  } = React.useContext(GlobalContext);
  const { state: authState, dispatch } = React.useContext(AuthContext);

  const {
    register,
    handleSubmit,
    setValue,
    watch,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
    defaultValues: {
      [input]: initialValue,
    },
  });
  const formData = watch();

  const makeRequests = async () => {
    if (!["create", "update", "delete", "custom"].includes(mode)) {
      return showToast(
        globalDispatch,
        "Mode must be create, update, delete or custom",
        5000,
        "error"
      );
    }
    if (!Array.isArray(data)) {
      return showToast(globalDispatch, "Data must be an list", 5000, "error");
    }
    const requestPromise = data?.map((item) => requestMode(mode, item));
    const results = await Promise.all(requestPromise);
    if (results.some((result) => !result.error) && onSuccess) {
      onSuccess();
    }
  };

  const requestMode = (mode, data) => {
    if (["create"].includes(mode)) {
      return createRequest(globalDispatch, dispatch, table, data, false);
    }
    if (["update"].includes(mode)) {
      return updateRequest(
        globalDispatch,
        dispatch,
        table,
        data?.id,
        data,
        false
      );
    }
    if (["delete"].includes(mode)) {
      return deleteRequest(
        globalDispatch,
        dispatch,
        table,
        data.id,
        null,
        false
      );
    }
    if (["custom"].includes(mode)) {
      return customRequest(
        globalDispatch,
        dispatch,
        {
          endpoint: options?.endpoint,
          method: "POST",
          payload: data,
        },
        RequestItems?.createModel,
        false
      );
    }
  };

  const editData = async (data) => {
    const result = await updateRequest(
      globalDispatch,
      dispatch,
      table,
      data?.id,
      data
    );

    if (!result?.error && onSuccess) {
      onSuccess();
    }
  };

  const inputUpdateData = async (data) => {
    const result = await updateRequest(
      globalDispatch,
      dispatch,
      table,
      data?.id,
      {
        [input]: formData[input],
      }
    );

    if (!result?.error && onSuccess) {
      onSuccess({ [input]: formData[input], id: result?.data });
    }
  };

  const inputCreateData = async (data) => {
    const result = await createRequest(globalDispatch, dispatch, table, {
      ...data,
      [input]: formData[input],
    });

    if (!result?.error && onSuccess) {
      onSuccess({ [input]: formData[input], id: result?.data });
    }
  };

  const createData = async (data) => {
    if (action === "move") return moveRequest(data);
    const result = await createRequest(globalDispatch, dispatch, table, data);

    if (!result?.error && onSuccess) {
      onSuccess();
    }
  };

  const deleteData = async (data) => {
    const result = await deleteRequest(
      globalDispatch,
      dispatch,
      table,
      data.id
    );

    if (!result?.error && onSuccess) {
      onSuccess();
    }
  };

  const customData = async (data) => {
    const result = await customRequest(
      globalDispatch,
      dispatch,
      {
        endpoint: options?.endpoint,
        method: options?.method,
        payload: data,
      },
      RequestItems.createModel
    );

    if (
      result &&
      result?.hasOwnProperty("error") &&
      !result?.error &&
      onSuccess
    ) {
      onSuccess(result);
    }
  };
  const inputData = () => {
    const data = formData[input];
    if (onSuccess) {
      onSuccess({ [input]: data });
    }
  };
  const manualData = (data) => {
    if (onSuccess) {
      onSuccess(data);
    }
  };
  const moveRequest = async (data) => {
    const result = await customRequest(
      globalDispatch,
      dispatch,
      {
        endpoint: "/v3/api/custom/qualitysign/inventory/move",
        method: "POST",
        payload: data,
      },
      RequestItems.createModel
    );

    if (!result?.error && onSuccess) {
      onSuccess(result);
    }
  };
  const requests = {
    create: createData,
    input_create: inputCreateData,
    input_update: inputUpdateData,
    update: editData,
    delete: deleteData,
    custom: customData,
    manual: manualData,
    input: inputData,
  };
  const onSubmit = async () => {
    if (multiple) {
      makeRequests();
    } else {
      const request = requests[mode];
      return request(data);
    }
  };

  React.useEffect(() => {
    if (!inputConfirmation) {
      setValue("confirm", action);
    }
  }, [inputConfirmation]);

  React.useEffect(() => {
    if (["input_update"].includes(mode)) {
      setValue(input, initialValue);
    }
  }, [mode]);

  return (
    // <div className={`px-5 ${multiple ? "flex justify-center" : ""}`}>
    <div className="!font-inter mx-auto flex h-fit flex-col items-center justify-start rounded leading-snug tracking-wide">
      <form
        className={`flex h-fit w-full flex-col text-start`}
        onSubmit={handleSubmit(onSubmit, (error) => {
          console.log("ERROR >>", error);
        })}
      >
        <div className="space-y-5">
          <div className="my-2">
            {customMessage ? (
              <div>{customMessage}</div>
            ) : (
              <div>
                Are you sure you want to {action}{" "}
                {(data?.id && data?.id?.length && data?.id?.length > 1) ||
                data?.length > 1
                  ? "these"
                  : "this"}{" "}
                {table?.split("_")?.join(" ")}?
              </div>
            )}
          </div>
          <div className={`!mb-10 ${inputConfirmation ? "" : "hidden"}`}>
            <MkdInput
              type={inputType}
              page={"items"}
              rows="5"
              name={
                ["input", "input_create", "input_update"].includes(mode)
                  ? input
                  : `confirm`
              }
              errors={errors}
              register={register}
              label={
                <div className="font-bold text-black">
                  Type{" "}
                  {["input", "input_create", "input_update"].includes(mode)
                    ? ""
                    : `'${action}'`}{" "}
                  below
                </div>
              }
              className={"grow resize-none"}
            />
          </div>

          <div className="mt-5 flex w-full grow gap-5">
            {disableCancel ? null : (
              <AddButton
                type="button"
                onClick={() => onClose()}
                disabled={
                  createModel?.loading ||
                  updateModel?.loading ||
                  deleteModel?.loading
                }
                showPlus={false}
                className="!text-primary-black grow self-end !border-gray-200 !bg-transparent font-bold"
              >
                Cancel
              </AddButton>
            )}
            <InteractiveButton
              type="submit"
              loading={
                createModel?.loading ||
                updateModel?.loading ||
                deleteModel?.loading
              }
              disabled={
                createModel?.loading ||
                updateModel?.loading ||
                deleteModel?.loading
              }
              className={`self-end rounded px-4 py-2 font-bold capitalize text-white ${
                disableCancel ? "!grow" : "!w-1/2"
              }`}
            >
              {action}
            </InteractiveButton>
          </div>
        </div>
      </form>
    </div>
  );
};

export default ActionConfirmation;
