import { yupResolver } from "@hookform/resolvers/yup";
import FormMultiSelect from "Components/FormMultiSelect";
import ConfirmModal from "Components/Modal/ConfirmModal";
import { createOrUpdateMangerPermissionByManagerPermissionIdForAdmin } from "Src/services/adminServices";
import { getAllMemberAssignedToClient } from "Src/services/clientService";
import { getAllMembersForManager } from "Src/services/managerServices";
import { deleteUserAPI, retrieveAllUserAPI } from "Src/services/userService";
import React, { useEffect, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { useNavigate, useParams } from "react-router-dom";
import { ClipLoader } from "react-spinners";
import * as yup from "yup";
import { AuthContext, tokenExpireError } from "../authContext";
import { GlobalContext, showToast } from "../globalContext";
import MkdSDK from "../utils/MkdSDK";
import CustomSelect from "Components/CustomSelect";
import CustomSelect2 from "Components/CustomSelect2";

let sdk = new MkdSDK();

const EditAdminUserPage = () => {
  const { dispatch, state: authState } = React.useContext(AuthContext);

  const schema = yup
    .object({
      email: yup.string().email().required(),
      password: yup.string(),
    })
    .required();

  const { dispatch: globalDispatch } = React.useContext(GlobalContext);
  const navigate = useNavigate();
  const params = useParams();
  const [clientData, setClientData] = useState({});
  const [oldEmail, setOldEmail] = useState("");
  const [id, setId] = useState(0);
  const [subscription, setSubscription] = React.useState(null);
  const [model, setModel] = useState(null);
  const [role, setRole] = React.useState("");
  const [members, setMembers] = React.useState([]);
  const [selectedMemberId, setSelectedMemberId] = React.useState("");
  const [isLoading, setIsLoading] = React.useState(false);

  const [producersForSelect, setProducersForSelect] = React.useState([]);
  const [selectedProducers, setSelectedProducers] = React.useState([]);

  const [showDeleteFileConfirmModal, setShowDeleteFileConfirmModal] =
    React.useState(false);

  const handleDeleteUserModalClose = () => {
    setShowDeleteFileConfirmModal(false);
  };

  const handleDeleteFileSubmit = () => {
    setShowDeleteFileConfirmModal(false);
  };

  const {
    register,
    handleSubmit,
    setError,
    setValue,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  });

  const selectRole = ["admin"];
  const selectStatus = [
    { key: "0", value: "Inactive" },
    { key: "2", value: "Suspend" },
    { key: "1", value: "Active" },
  ];

  const onSubmit = async (data) => {
    try {
      if (oldEmail !== data.email) {
        const emailResult = await sdk.updateEmailByAdmin(data.email, id);
        if (!emailResult.error) {
          showToast(globalDispatch, "Email Updated", 1000);
        } else {
          if (emailResult.validation) {
            const keys = Object.keys(emailResult.validation);
            for (let i = 0; i < keys.length; i++) {
              const field = keys[i];
              setError(field, {
                type: "manual",
                message: emailResult.validation[field],
              });
            }
          }
        }
      }

      if (selectedProducers.length > 0) {
        const res =
          await createOrUpdateMangerPermissionByManagerPermissionIdForAdmin(
            selectedProducers.map((elem) => elem.value),
            params?.id
          );
        if (res.error) {
          showToast(
            globalDispatch,
            "Something went wrong with assigning member",
            6000,
            "error"
          );
        }
      }

      if (data.password.length > 0) {
        const passwordResult = await sdk.updatePasswordByAdmin(
          data.password,
          id
        );
        if (!passwordResult.error) {
          showToast(globalDispatch, "Password Updated", 2000);
        } else {
          if (passwordResult.validation) {
            const keys = Object.keys(passwordResult.validation);
            for (let i = 0; i < keys.length; i++) {
              const field = keys[i];
              setError(field, {
                type: "manual",
                message: passwordResult.validation[field],
              });
            }
          }
        }
      }

      sdk.setTable("user");

      const result = await sdk.callRestAPI(
        {
          id,
          email: data.email,
          first_name: data.first_name,
          last_name: data.last_name,
          status: data.status,
          subscription: subscription && parseInt(subscription),
        },
        "PUT"
      );

      if (!result.error) {
        showToast(globalDispatch, "User updated successfully", 4000);
        navigate("/admin/users");
      } else {
        if (result.validation) {
          const keys = Object.keys(result.validation);
          for (let i = 0; i < keys.length; i++) {
            const field = keys[i];
            setError(field, {
              type: "manual",
              message: result.validation[field],
            });
          }
        }
      }
    } catch (error) {
      setError("email", {
        type: "manual",
        message: error.message,
      });
      tokenExpireError(dispatch, error.message);
    }
  };

  const retrieveAllUsers = async () => {
    try {
      let filter = {
        role: "member",
      };
      const result = await retrieveAllUserAPI(1, 4000, filter);
      if (!result.error) {
        if (result.list.length > 0) {
          let list = result.list;
          // concat first_name and last_name into user_name
          // then sort by ascending order of user_name
          list = list.map((row) => {
            row.user_name = row.first_name + " " + row.last_name;
            return { value: row.id, label: row.user_name };
          });

          list = list.sort((a, b) => {
            return a.label.localeCompare(b.label);
          });

          setProducersForSelect(list);
        }
      }
    } catch (error) {
      tokenExpireError(dispatch, error.message);
    }
  };

  const setAssignedMembers = async () => {
    const result = await getAllMembersForManager(params?.id);
    if (!result.error) {
      if (result.list.length > 0) {
        let list = result.list;

        list = list.map((row) => {
          row.user_name = row.first_name + " " + row.last_name;
          return { value: row.id, label: row.user_name };
        });

        list = list.sort((a, b) => {
          return a.label.localeCompare(b.label);
        });

        // const keyID = list.map((row) => row.value);

        setSelectedProducers(list);
      }
    }
  };

  React.useEffect(() => {
    globalDispatch({
      type: "SETPATH",
      payload: {
        path: "users",
      },
    });

    (async function () {
      try {
        setIsLoading(true);
        await retrieveAllUsers();

        await setAssignedMembers();

        sdk.setTable("user");
        const result = await sdk.callRestAPI({ id: Number(params?.id) }, "GET");

        if (!result.error) {
          setRole(result?.model?.role);
          setSubscription(result?.model?.subscription);
          setValue("email", result.model.email);
          setValue("status", result.model.status);
          setOldEmail(result.model.email);
          setId(result.model.id);
          setModel(result?.model);
          setIsLoading(false);
          // await getOneManagerPermissionForAdmin(result.model.id);
          // await createOrUpdateMangerPermissionByManagerPermissionIdForAdmin(
          //   { member_ids: [9] },
          //   result.model.id
          // );
        }
      } catch (error) {
        setIsLoading(false);

        tokenExpireError(dispatch, error.message);
      }
    })();
  }, []);

  useEffect(() => {
    (async function () {
      const res = await getAllMemberAssignedToClient(model?.client_id);
      console.log(model);

      if (!res?.error) {
        const memberIds = res.model.members.map((obj) => obj.id);
        setAssignedMembers(memberIds);
        setClientData(res.model);
      }
    })();
  }, [role, model]);

  const handleSelectedProducers = (names) => {
    if (names.length === 0) {
      setSelectedProducers([]);
    } else {
      setSelectedProducers(names);
    }
  };

  const deleteUser = async () => {
    try {
      console.log(params.id, model.email);
      const res = await deleteUserAPI(params.id, model.email);

      showToast(globalDispatch, "User deleted successfully", 4000);
      setShowDeleteFileConfirmModal(false);
      navigate("/admin/users");
    } catch (error) {
      showToast(globalDispatch, "User deleted successfully", 4000, "error");
    }
  };

  const selectUserRef = useRef(null);

  if (isLoading) {
    return (
      <div className="flex justify-center items-center h-screen">
        <ClipLoader color="#fff" size={30} />
      </div>
    );
  }
  return (
    <>
      <div className="p-4 h-full max-w-screen md:p-4 lg:p-6 xl:p-8">
        <div className="rounded border shadow-default border-strokedark bg-boxdark dark:border-strokedark dark:bg-boxdark">
          {/* Header Section */}
          <div className="sm:px-6.5 border-b border-strokedark px-4 py-4 dark:border-strokedark">
            <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
              <h3 className="text-xl font-medium text-white">Edit User</h3>
              {authState?.role === "admin" && (
                <div className="flex flex-wrap gap-3 items-center">
                  <button
                    type="button"
                    onClick={() => setShowDeleteFileConfirmModal(true)}
                    className="inline-flex items-center justify-center rounded-md bg-danger px-6 py-2.5 text-center font-medium text-white hover:bg-opacity-90"
                  >
                    Delete User
                  </button>
                </div>
              )}
            </div>
          </div>

          {/* Form Content */}
          <div className="p-4 md:p-6 2xl:p-10">
            <form onSubmit={handleSubmit(onSubmit)}>
              <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
                {/* Email Field */}
                <div className="space-y-4">
                  <div className="pb-4 border-b border-strokedark dark:border-strokedark">
                    <label className="text-sm text-gray-400">Email</label>
                    <input
                      type="email"
                      placeholder="Email"
                      {...register("email")}
                      className="mt-1 w-full rounded border-[1.5px] border-strokedark bg-form-input px-5 py-3 font-medium text-white outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:border-form-strokedark dark:bg-form-input"
                    />
                    {errors.email?.message && (
                      <p className="mt-1 text-sm text-danger">
                        {errors.email.message}
                      </p>
                    )}
                  </div>

                  {/* Password Field */}
                  <div className="pb-4 border-b border-strokedark dark:border-strokedark">
                    <label className="text-sm text-gray-400">Password</label>
                    <input
                      type="password"
                      placeholder="******************"
                      {...register("password")}
                      className="mt-1 w-full rounded border-[1.5px] border-strokedark bg-form-input px-5 py-3 font-medium text-white outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:border-form-strokedark dark:bg-form-input"
                    />
                    {errors.password?.message && (
                      <p className="mt-1 text-sm text-danger">
                        {errors.password.message}
                      </p>
                    )}
                  </div>

                  {/* Status Field */}
                  <div className="pb-4 border-b border-strokedark dark:border-strokedark">
                    <label className="text-sm text-gray-400">Status</label>
                    <CustomSelect2
                      register={register}
                      name="status"
                      label="Status"
                    >
                      {selectStatus.map((elem) => {
                        return <option value={elem?.key}>{elem?.value}</option>;
                      })}
                    </CustomSelect2>
                  </div>
                </div>

                <div className="space-y-4">
                  {/* Manager Section */}
                  {role === "manager" && (
                    <div className="pb-4 border-b border-strokedark dark:border-strokedark">
                      <label className="mb-1 text-sm text-gray-400">
                        Assign Members to Manager
                      </label>

                      <FormMultiSelect
                        selectRef={selectUserRef}
                        values={selectedProducers}
                        onValuesChange={handleSelectedProducers}
                        options={producersForSelect}
                        placeholder="Producers"
                      />

                      <p className="mt-1 text-sm text-meta-5">
                        Currently assigned Members are prefilled in the field
                        below. Modify by selection and submission.
                      </p>
                    </div>
                  )}

                  {/* Subscription Section */}
                  {role === "member" && (
                    <div className="pb-4 border-b border-strokedark dark:border-strokedark">
                      <label className="text-sm text-gray-400">
                        Subscription
                      </label>
                      <CustomSelect2
                        label="Subscription Status"
                        register={register}
                        name="status"
                      >
                        {selectStatus.map((option) => {
                          return (
                            <option value={option?.key}>{option?.value}</option>
                          );
                        })}
                      </CustomSelect2>
                    </div>
                  )}

                  {/* Client Members Section */}
                  {role === "client" && (
                    <div className="pb-4 border-b border-strokedark dark:border-strokedark">
                      <label className="text-sm text-gray-400">
                        Members assigned to:
                      </label>
                      <p className="mt-1 text-base font-medium text-white">
                        {clientData?.members
                          ?.map((elem) => elem?.full_name)
                          .join(", ") || "None"}
                      </p>
                    </div>
                  )}
                </div>
              </div>

              {/* Form Actions */}
              <div className="flex gap-4 items-center mt-6">
                <button
                  type="submit"
                  className="inline-flex items-center justify-center rounded-md bg-primary px-6 py-2.5 text-center font-medium text-white hover:bg-opacity-90"
                >
                  Update
                </button>
                <button
                  type="button"
                  onClick={() => navigate(-1)}
                  className="inline-flex items-center justify-center rounded-md border border-strokedark bg-meta-4 px-6 py-2.5 text-center font-medium text-white hover:bg-opacity-90"
                >
                  Cancel
                </button>
              </div>
            </form>
          </div>
        </div>
      </div>

      {/* Delete Confirmation Modal */}
      {showDeleteFileConfirmModal && (
        <ConfirmModal
          confirmText="Are you sure you want to delete this user?"
          setModalClose={handleDeleteUserModalClose}
          setFormYes={deleteUser}
        />
      )}
    </>
  );
};

export default EditAdminUserPage;
