import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import MkdSDK from "@/utils/MkdSDK";
import { GlobalContext, showToast } from "@/context/Global";
import { AuthContext, tokenExpireError } from "@/context/Auth";
import { InteractiveButton } from "@/components/InteractiveButton";
import ModalPrompt from "@/components/Modal/ModalPrompt";
import { FaCloudUploadAlt } from "react-icons/fa";
import Skeleton from "@/components/Skeleton/Skeleton";

let sdk = new MkdSDK();

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

  const { dispatch } = React.useContext(AuthContext);
  const [oldEmail, setOldEmail] = useState("");
  const [fileObj, setFileObj] = React.useState({});
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isEditModalOpen, setIsEditModalOpen] = useState(false);
  const [oldPhoto, setOldPhoto] = useState("");
  const [isUploadedPhoto, setIsUploadedPhoto] = useState(false);
  const [submitLoading, setSubmitLoading] = useState(false);
  const [activeTab, setActiveTab] = useState("Profile");
  const [defaultValues, setDefaultValues] = useState({});
  const [loading, setLoading] = useState(true);
  const { dispatch: globalDispatch } = React.useContext(GlobalContext);
  const {
    register,
    handleSubmit,
    setError,
    setValue,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  });

  const previewImage = (field, target, multiple = false) => {
    setIsUploadedPhoto(true);
    let tempFileObj = fileObj;
    if (multiple) {
      if (tempFileObj[field]) {
        tempFileObj[field] = [
          ...tempFileObj[field],
          {
            file: target.files[0],
            tempFile: {
              url: URL.createObjectURL(target.files[0]),
              name: target.files[0].name,
              type: target.files[0].type,
            },
          },
        ];
      } else {
        tempFileObj[field] = [
          {
            file: target.files[0],
            tempFile: {
              url: URL.createObjectURL(target.files[0]),
              name: target.files[0].name,
              type: target.files[0].type,
            },
          },
        ];
      }
    } else {
      tempFileObj[field] = {
        file: target.files[0],
        tempURL: URL.createObjectURL(target.files[0]),
      };
    }
    setFileObj({ ...tempFileObj });
  };

  async function fetchData() {
    setLoading(true);
    try {
      const result = await sdk.getProfile();
      if (!result.error) {
        setDefaultValues(result);
        setValue("email", result?.email);
        setValue("first_name", result?.first_name);
        setValue("last_name", result?.last_name);
        setOldEmail(result?.email);
        setOldPhoto(result?.photo);
        dispatch({
          type: "UPDATE_PROFILE",
          payload: result,
        });
        setLoading(false);
      }
    } catch (error) {
      tokenExpireError(
        dispatch,
        error.response.data.message
          ? error.response.data.message
          : error.message
      );
    }
  }

  const onSubmit = async (data) => {
    if (
      defaultValues.email === data.email &&
      defaultValues.first_name === data.first_name &&
      defaultValues.last_name === data.last_name &&
      !isUploadedPhoto &&
      !data.password
    ) {
      closeModal();
      return showToast(globalDispatch, "No Changes Available", 1000);
    }

    setDefaultValues(data);
    try {
      setSubmitLoading(true);
      if (fileObj && fileObj["photo"] && fileObj["photo"]?.file) {
        let formData = new FormData();
        formData.append("file", fileObj["photo"]?.file);
        let uploadResult = await sdk.uploadImage(formData);
        data["photo"] = uploadResult.url;
        showToast(globalDispatch, "Profile Photo Updated", 1000);
      }

      const result = await sdk.updateProfile({
        first_name: data.first_name || defaultValues?.first_name,
        last_name: data.last_name || defaultValues?.last_name,
        photo: data.photo || oldPhoto,
      });

      if (!result.error) {
        showToast(globalDispatch, "Profile Updated", 4000);
        closeModal();
        fetchData();
      } 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],
            });
          }
        }
        closeModal();
      }
      if (oldEmail !== data.email) {
        const emailresult = await sdk.updateEmail(data.email);
        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],
              });
            }
          }
        }
        closeModal();
      }

      if (data.password?.length > 0) {
        const passwordresult = await sdk.updatePassword(data.password);
        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],
              });
            }
          }
        }
      }
      data.photo = "";
      await fetchData();
      setSubmitLoading(false);
    } catch (error) {
      setSubmitLoading(false);
      setError("email", {
        type: "manual",
        message: error.response.data.message
          ? error.response.data.message
          : error.message,
      });
      tokenExpireError(
        dispatch,
        error.response.data.message
          ? error.response.data.message
          : error.message
      );
    }
  };

  const onDeleteProfile = async () => {
    setFileObj({});
    setOldPhoto("");
    setIsUploadedPhoto(true);
  };

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

    fetchData();
  }, []);

  const openModalEdit = () => {
    setIsEditModalOpen(true);
  };

  const closeModal = () => {
    setIsModalOpen(false);
    setIsEditModalOpen(false);
    setOldPhoto(defaultValues?.photo);
    setFileObj({});
    setIsUploadedPhoto(false);
  };

  return (
    <div className="w-full">
      <div className="flex items-center border-b border-b-[#E0E0E0] px-8 py-3 text-[#8D8D8D]">
        <div className="flex items-center space-x-6">
          <div
            className={`cursor-pointer rounded-lg px-3 py-1 ${activeTab === "Profile" ? "bg-[#f4f4f4] text-[#525252]" : ""
              }`}
            onClick={() => setActiveTab("Profile")}
          >
            Profile
          </div>
          <div
            className={`cursor-pointer rounded-lg px-3 py-1 ${activeTab === "Security" ? "bg-[#f4f4f4] text-[#525252]" : ""
              }`}
            onClick={() => setActiveTab("Security")}
          >
            Security
          </div>
        </div>
      </div>
      <main>
        {/* Profile Tab */}
        {activeTab === "Profile" && (
          <div className="rounded bg-white">
            <form onSubmit={handleSubmit(onSubmit)}>
              <p className="text-xs italic text-red-500">
                {errors.photo?.message}
              </p>
              <div className="mx-10 mt-4 max-w-lg">
                <div className="mb-3 flex items-center justify-between">
                  <p className="mb-3	text-lg	font-semibold text-gray-900">
                    Personal Details
                  </p>
                  {!loading ? (
                    <p
                      className="cursor-pointer	text-base	font-semibold text-indigo-600"
                      onClick={openModalEdit}
                    >
                      Edit
                    </p>
                  ) : (
                    <div className="h-10">
                      <Skeleton count={1} counts={[1]} />
                    </div>
                  )}
                </div>

                <div className="mb-3 flex items-center justify-between">
                  <div className="flex items-start gap-x-24">
                    <p className="text-base	font-medium	text-gray-600">
                      Profile Picture
                    </p>

                    {loading ? (
                      <div className="flex items-center">
                        <div className="h-[120px] w-[120px] flex-1 overflow-hidden rounded-2xl">
                          <Skeleton count={4} counts={[1]} />
                        </div>
                      </div>
                    ) : defaultValues?.photo ? (
                      <div className="relative flex h-[100px] w-[100px] items-center rounded-lg py-2">
                        <img
                          className="h-[100px] w-[100px] rounded-lg object-cover"
                          src={defaultValues?.photo}
                          alt=""
                        />
                      </div>
                    ) : (
                      <div className="flex items-center gap-4 py-2">
                        <div className="flex h-[100px] w-[100px] items-center justify-center rounded-lg border bg-slate-300 object-cover">
                          <span className="text-xs">No Image</span>
                        </div>
                      </div>
                    )}
                  </div>
                </div>

                <div className="mb-3 flex items-center justify-between">
                  <div className="flex items-center gap-x-[7.5rem]">
                    <p className="text-base	font-medium	text-gray-600">
                      First Name
                    </p>
                    <p className="text-base	font-medium	text-gray-900">
                      {defaultValues?.first_name}
                    </p>
                  </div>
                </div>

                <div className="mb-3 flex items-center justify-between">
                  <div className="flex items-center gap-x-[7.5rem]">
                    <p className="text-base	font-medium	text-gray-600">
                      Last Name
                    </p>
                    <p className="text-base	font-medium	text-gray-900">
                      {defaultValues?.last_name}
                    </p>
                  </div>
                </div>
                <div className="mb-6 flex items-center justify-between text-left">
                  <div className="flex items-center gap-x-40">
                    <p className="text-base	font-medium text-gray-600">Email</p>
                    <p className="text-base	font-medium	text-gray-900">
                      {oldEmail}
                    </p>
                  </div>
                </div>
              </div>
            </form>
          </div>
        )}

        {/* Security tab */}
        {activeTab === "Security" && (
          <div className="rounded bg-white px-10 py-6">
            <form onSubmit={handleSubmit(onSubmit)} className="max-w-lg">
              <div className="">
                <div className="mb-6">
                  <label className="mb-2 block text-sm font-bold text-gray-700">
                    Password
                  </label>
                  <input
                    {...register("password")}
                    name="password"
                    className={
                      "focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none"
                    }
                    id="password"
                    type="password"
                    placeholder="******************"
                  />
                  <p className="text-xs italic text-red-500">
                    {errors.password?.message}
                  </p>
                </div>
                <div className="flex items-center justify-between">
                  <InteractiveButton
                    className="focus:shadow-outline rounded bg-indigo-600 px-4 py-2 font-bold text-white hover:bg-indigo-600 focus:outline-none disabled:cursor-not-allowed"
                    type="submit"
                    loading={submitLoading}
                    disabled={submitLoading}
                  >
                    Update
                  </InteractiveButton>
                </div>
              </div>
            </form>
          </div>
        )}
        {isModalOpen && (
          <ModalPrompt
            closeModalFunction={closeModal}
            title={`Are you sure?`}
            message={`Are you sure you want to delete profile picture? `}
            acceptText={`DELETE`}
            rejectText={`CANCEL`}
          />
        )}
        {isEditModalOpen && (
          <EditInfoModal
            title="Edit Personal Details"
            isOpen={openModalEdit}
            onClose={closeModal}
            handleSubmit={handleSubmit}
            onSubmit={onSubmit}
            register={register}
            submitLoading={submitLoading}
            errors={errors}
            oldPhoto={oldPhoto}
            fileObj={fileObj}
            onDeleteProfile={onDeleteProfile}
            previewImage={previewImage}
            oldEmail={oldEmail}
          />
        )}
      </main>
    </div>
  );
};

export default AdminProfilePage;

export const EditInfoModal = (props) => {
  const {
    title,
    isOpen,
    onClose,
    handleSubmit,
    onSubmit,
    register,
    submitLoading,
    errors,
    oldPhoto,
    fileObj,
    onDeleteProfile,
    previewImage,
    oldEmail,
  } = props;
  const [emailConfirm, setEmailConfirm] = useState(false);
  const [values, setValues] = useState({
    email: "",
  });
  const modalRef = React.useRef(null);

  useEffect(() => {
    setValues({ ...values, email: oldEmail });
    setEmailConfirm(false);
  }, [oldEmail]);

  const handleChange = (prop) => (event) => {
    if (prop === "email") {
      setValues({ ...values, [prop]: event.target.value });
    }
  };

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (modalRef.current && !modalRef.current.contains(event.target)) {
        onClose();
      }
    };

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
    } else {
      document.removeEventListener('mousedown', handleClickOutside);
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [isOpen, onClose]);

  return (
    <div className={`fixed inset-0 z-[100] ${isOpen ? 'block' : 'hidden'}`}>
      <div className={`fixed inset-0 bg-gray-800 bg-opacity-75 ${isOpen ? 'block' : 'hidden'}`}></div>
      <div className="fixed inset-0 z-20 overflow-y-auto">
        <div className="flex min-h-screen items-end justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0">
          <div className="fixed inset-0 transition-opacity">
            <div className="absolute inset-0 bg-gray-500 opacity-75"></div>
          </div>
          <span
            className="hidden sm:inline-block sm:h-screen sm:align-middle"
            aria-hidden="true"
          >
            &#8203;
          </span>
          <div ref={modalRef} className="inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
            <div className="flex items-center justify-between">
              <div className="text-xl font-semibold leading-6 text-gray-900">
                {title}
              </div>
              <button
                className="text-gray-500 hover:text-gray-700 focus:outline-none"
                onClick={onClose}
              >
                <svg
                  className="h-6 w-6"
                  fill="none"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth="2"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path d="M6 18L18 6M6 6l12 12"></path>
                </svg>
              </button>
            </div>
            <form onSubmit={handleSubmit(onSubmit)} className="max-w-lg">
              <div className="py-5">
                <label
                  htmlFor="first_name"
                  className="mb-1 block text-sm font-medium text-gray-700"
                >
                  Upload Profile
                </label>
                {oldPhoto ? (
                  <div>
                    <div className="hover-container relative flex h-[100px] w-[100px] items-center rounded-lg">
                      <img
                        className="h-[100px] w-[100px] rounded-lg object-cover"
                        src={fileObj["photo"]?.tempURL || oldPhoto}
                        alt=""
                      />
                      <button
                        className="file-wrapper absolute bottom-0 left-0 block"
                        disabled={submitLoading}
                      >
                        <div className="!z-40 !cursor-pointer rounded-bl-lg rounded-tr-xl !bg-[#4F46E5] p-1">
                          <FaCloudUploadAlt className="text-[1.3rem] text-white" />
                        </div>
                        <input
                          id="photo"
                          type="file"
                          placeholder="Photo"
                          name="photo"
                          onChange={(e) => previewImage("photo", e.target)}
                          className="absolute left-0 top-0 flex h-full w-full !cursor-pointer opacity-0"
                        />
                      </button>
                      <div className="visible-btn absolute right-0 top-0 hidden">
                        <InteractiveButton
                          onClick={onDeleteProfile}
                          loading={submitLoading}
                          disabled={submitLoading}
                          className="!h-[1.4rem] cursor-pointer !rounded-none !rounded-bl-xl !rounded-tr-lg !bg-red-500 text-sm font-semibold"
                        >
                          X
                        </InteractiveButton>
                      </div>
                    </div>
                  </div>
                ) : (
                  <div className="flex h-[100px] w-[100px] items-center justify-center rounded-lg border object-cover">
                    <div className="relative">
                      {fileObj["photo"]?.tempURL ? (
                        <img
                          className="h-[100px] w-[100px] rounded-lg object-cover"
                          src={fileObj["photo"]?.tempURL || oldPhoto}
                          alt=""
                        />
                      ) : (
                        <button disabled={submitLoading}>
                          <div>
                            <FaCloudUploadAlt className="text-[35px] text-blue-950" />
                          </div>
                          <input
                            id="photo"
                            type="file"
                            placeholder="Photo"
                            name="photo"
                            onChange={(e) => previewImage("photo", e.target)}
                            className="absolute left-0 top-0 flex h-full w-full !cursor-pointer opacity-0"
                          />
                        </button>
                      )}
                    </div>
                  </div>
                )}
                <div className="mt-3">
                  <label
                    htmlFor="first_name"
                    className="mb-1 block text-sm font-medium text-gray-700"
                  >
                    First Name
                  </label>
                  <input
                    className="focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none"
                    id="first_name"
                    type="text"
                    placeholder={`Enter First Name`}
                    name="first_name"
                    {...register("first_name")}
                  />
                  <p className="text-xs italic text-red-500">
                    {errors?.id?.message}
                  </p>
                </div>
                <div className="mt-3">
                  <label
                    htmlFor="last_name"
                    className="mb-1 block text-sm font-medium text-gray-700"
                  >
                    Last Name
                  </label>
                  <input
                    className="focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none"
                    id="last_name"
                    type="text"
                    placeholder={`Enter last Name`}
                    name="last_name"
                    {...register("last_name")}
                  />
                  <p className="text-xs italic text-red-500">
                    {errors?.id?.message}
                  </p>
                </div>
                {emailConfirm && oldEmail !== values.email ? (
                  <div className="mt-3 flex">
                    <div className="mr-2">
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        width="20"
                        height="20"
                        viewBox="0 0 20 20"
                        fill="none"
                      >
                        <path
                          fillRule="evenodd"
                          clipRule="evenodd"
                          d="M10.0003 1.66663C5.39795 1.66663 1.66699 5.39759 1.66699 9.99996C1.66699 14.6023 5.39795 18.3333 10.0003 18.3333C14.6027 18.3333 18.3337 14.6023 18.3337 9.99996C18.3337 5.39759 14.6027 1.66663 10.0003 1.66663ZM8.33366 9.16663C8.33366 8.82145 8.61348 8.54163 8.95866 8.54163H10.0003C10.3455 8.54163 10.6253 8.82145 10.6253 9.16663L10.6253 13.5416C10.6253 13.8868 10.3455 14.1666 10.0003 14.1666C9.65515 14.1666 9.37533 13.8868 9.37533 13.5416L9.37532 9.79163H8.95866C8.61348 9.79163 8.33366 9.5118 8.33366 9.16663ZM10.0003 6.04163C9.65515 6.04163 9.37533 6.32145 9.37533 6.66663C9.37533 7.0118 9.65515 7.29163 10.0003 7.29163C10.3455 7.29163 10.6253 7.0118 10.6253 6.66663C10.6253 6.32145 10.3455 6.04163 10.0003 6.04163Z"
                          fill="#4F46E5"
                        />
                      </svg>
                    </div>
                    <div>
                      <p className="mb-1	text-sm	font-medium text-gray-600">
                        We've sent an email to: {values?.email}
                      </p>
                      <p className="mb-2	text-sm	font-semibold text-gray-900"></p>
                      <p className="mb-2	text-sm	font-medium text-gray-600">
                        In order to complete the email update click the
                        confirmation link.
                      </p>
                      <p className="mb-2	text-sm	font-medium text-gray-600">
                        (the link expires in 24 hours)
                      </p>
                    </div>
                  </div>
                ) : (
                  <div className="mt-3">
                    <label
                      htmlFor="email"
                      className="mb-1 block text-sm font-medium text-gray-700"
                    >
                      Email
                    </label>
                    <input
                      className="focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none"
                      id={"email"}
                      type="text"
                      placeholder={`Enter Email`}
                      name={"email"}
                      {...register("email")}
                      onChange={handleChange("email")}
                    />
                    <p className="text-xs italic text-red-500">
                      {errors?.id?.message}
                    </p>
                  </div>
                )}
              </div>

              <div className="mt-4 flex justify-between gap-10">
                <button
                  className="mr-2 w-full rounded-md border border-gray-300 px-4 py-1.5 text-gray-700	"
                  onClick={onClose}
                >
                  Cancel
                </button>

                <InteractiveButton
                  className="focus:shadow-outline !h-[2.5rem] w-full rounded-md bg-indigo-500 px-4 py-2 font-bold text-white hover:bg-indigo-600 focus:outline-none disabled:cursor-not-allowed"
                  type="submit"
                  loading={submitLoading}
                  disabled={submitLoading}
                  onClick={() => setEmailConfirm(true)}
                >
                  Save
                </InteractiveButton>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
};

