import { AppDispatch } from "app/store";
import React, { useCallback, useEffect, useState } from "react";
import styles from "styles/app.module.scss";
import { useDispatch, useSelector } from "react-redux";
import { useTranslation } from "react-i18next";
import { USER_ROLES } from "components/auth/constants";
import {
  changeUpdateAuthorId,
  changeUpdateAutoRenew,
  changeUpdateEncryption,
  changeUpdateEncryptionPassword,
  changeUpdateNotification,
  changeUpdatePrompt,
  changeUpdateRole,
  changeHasPasswordMask,
  cleanupUpdateUser,
  selectHasPasswordMask,
  selectIsLoading,
  selectUpdateUser,
  selectUpdateValidationErrors,
  updateUserAsync,
  listUsersAsync,
} from "features/user";
import { getTranslationID } from "translation";
import close from "../../assets/images/close.svg";
import progress_activit from "../../assets/images/progress_activit.svg";

interface UserUpdatePopupProps {
  isOpen: boolean;
  onClose: () => void;
  clearUserSearchInputs: () => void;
}

export const UserUpdatePopup: React.FC<UserUpdatePopupProps> = (props) => {
  const { isOpen, onClose, clearUserSearchInputs } = props;
  const dispatch: AppDispatch = useDispatch();
  const { t } = useTranslation();
  const closePopup = useCallback(() => {
    setIsPushCreateButton(false);
    dispatch(cleanupUpdateUser());
    onClose();
  }, [onClose, dispatch]);

  const {
    hasErrorEmptyAuthorId,
    hasErrorIncorrectAuthorId,
    hasErrorIncorrectEncryptionPassword,
  } = useSelector(selectUpdateValidationErrors);

  const [isPasswordHide, setIsPasswordHide] = useState<boolean>(true);
  const [isPushCreateButton, setIsPushCreateButton] = useState<boolean>(false);
  const user = useSelector(selectUpdateUser);

  const isLoading = useSelector(selectIsLoading);

  const hasPasswordMask = useSelector(selectHasPasswordMask);

  const [canChangeRole, setCanChangeRole] = useState(true);

  // 開閉時のみ実行
  useEffect(() => {
    setCanChangeRole(user.role === USER_ROLES.NONE);
    setIsPasswordHide(true);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen]);

  const onUpdateUser = useCallback(async () => {
    setIsPushCreateButton(true);

    if (
      hasErrorEmptyAuthorId ||
      hasErrorIncorrectAuthorId ||
      hasErrorIncorrectEncryptionPassword
    ) {
      return;
    }

    const { meta } = await dispatch(updateUserAsync());
    setIsPushCreateButton(false);

    if (meta.requestStatus === "fulfilled") {
      closePopup();
      clearUserSearchInputs();
      dispatch(listUsersAsync());
    }
  }, [
    dispatch,
    closePopup,
    hasErrorEmptyAuthorId,
    hasErrorIncorrectAuthorId,
    hasErrorIncorrectEncryptionPassword,
  ]);

  return (
    <div className={`${styles.modal} ${isOpen ? styles.isShow : ""}`}>
      <div className={styles.modalBox}>
        <p className={styles.modalTitle}>
          {t(getTranslationID("userListPage.label.editUser"))}
          <button type="button" onClick={closePopup}>
            <img src={close} className={styles.modalTitleIcon} alt="close" />
          </button>
        </p>
        <form className={styles.form}>
          <dl className={`${styles.formList} ${styles.hasbg}`}>
            <dt className={styles.formTitle}>
              {t(getTranslationID("userListPage.label.personal"))}
            </dt>
            <dt>{t(getTranslationID("userListPage.label.name"))}</dt>
            <dd>
              <input
                type="text"
                size={40}
                value={user.name}
                className={styles.formInput}
                readOnly
              />
            </dd>
            <dt>{t(getTranslationID("userListPage.label.email"))}</dt>
            <dd>
              <input
                type="email"
                size={40}
                value={user.email}
                className={styles.formInput}
                readOnly
              />
            </dd>
            <dt>{t(getTranslationID("userListPage.label.role"))}</dt>
            <dd>
              <label htmlFor={`edit_${USER_ROLES.AUTHOR}`}>
                <input
                  id={`edit_${USER_ROLES.AUTHOR}`}
                  type="radio"
                  name="role"
                  className={styles.formRadio}
                  checked={user.role === USER_ROLES.AUTHOR}
                  onChange={() => {
                    dispatch(changeUpdateRole({ role: USER_ROLES.AUTHOR }));
                  }}
                  disabled={!canChangeRole}
                />
                {t(getTranslationID("userListPage.label.author"))}
              </label>
              <label htmlFor={`edit_${USER_ROLES.TYPIST}`}>
                <input
                  id={`edit_${USER_ROLES.TYPIST}`}
                  type="radio"
                  name="role"
                  className={styles.formRadio}
                  checked={user.role === USER_ROLES.TYPIST}
                  onChange={() => {
                    dispatch(changeUpdateRole({ role: USER_ROLES.TYPIST }));
                  }}
                  disabled={!canChangeRole}
                />
                {t(getTranslationID("userListPage.label.transcriptionist"))}
              </label>
              <label htmlFor={`edit_${USER_ROLES.NONE}`}>
                <input
                  id={`edit_${USER_ROLES.NONE}`}
                  type="radio"
                  name="role"
                  className={styles.formRadio}
                  checked={user.role === USER_ROLES.NONE}
                  onChange={() => {
                    dispatch(changeUpdateRole({ role: USER_ROLES.NONE }));
                  }}
                  disabled={!canChangeRole}
                />
                {t(getTranslationID("userListPage.label.none"))}
              </label>
            </dd>

            {/** Author 選択時に表示 */}
            {user.role === USER_ROLES.AUTHOR && (
              <div className={styles.slideSet}>
                <dt>{t(getTranslationID("userListPage.label.authorID"))}</dt>
                <dd>
                  <input
                    type="text"
                    size={40}
                    maxLength={16}
                    autoComplete="off"
                    value={user.authorId}
                    className={styles.formInput}
                    onChange={(e) => {
                      dispatch(
                        changeUpdateAuthorId({
                          authorId: e.target.value.toUpperCase(),
                        })
                      );
                    }}
                  />
                  {isPushCreateButton && hasErrorEmptyAuthorId && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID("signupPage.message.inputEmptyError")
                      )}
                    </span>
                  )}
                  {isPushCreateButton && hasErrorIncorrectAuthorId && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID(
                          "userListPage.message.authorIdIncorrectError"
                        )
                      )}
                    </span>
                  )}
                </dd>
                <dt>{t(getTranslationID("userListPage.label.encryption"))}</dt>
                <dd>
                  <label htmlFor="Encryption">
                    <input
                      type="checkbox"
                      className={styles.formCheck}
                      checked={user.encryption}
                      onChange={(e) => {
                        dispatch(
                          changeUpdateEncryption({
                            encryption: e.target.checked,
                          })
                        );
                      }}
                    />
                  </label>
                  {/** Encryptionチェックでパスワード欄表示 */}
                  <p
                    className={`${styles.encryptionPass} ${
                      user.encryption ? styles.isShow : ""
                    }`}
                  >
                    {t(
                      getTranslationID("userListPage.label.encryptionPassword")
                    )}
                    <input
                      type={isPasswordHide ? "password" : "text"}
                      size={40}
                      maxLength={16}
                      autoComplete="new-password"
                      value={
                        hasPasswordMask
                          ? "********"
                          : user.encryptionPassword ?? ""
                      }
                      className={`${styles.formInput} ${styles.password}`}
                      onFocus={() => {
                        if (hasPasswordMask) {
                          dispatch(
                            changeHasPasswordMask({ hasPasswordMask: false })
                          );
                          dispatch(
                            changeUpdateEncryptionPassword({
                              encryptionPassword: "",
                            })
                          );
                        }
                      }}
                      onChange={(e) => {
                        if (!hasPasswordMask) {
                          dispatch(
                            changeUpdateEncryptionPassword({
                              encryptionPassword: e.target.value,
                            })
                          );
                        }
                      }}
                    />
                    <span
                      className={styles.formIconEye}
                      onClick={() => {
                        setIsPasswordHide(!isPasswordHide);
                      }}
                      onKeyDown={() => {
                        setIsPasswordHide(!isPasswordHide);
                      }}
                      role="button"
                      tabIndex={0}
                      aria-label="IconEye"
                    />
                    {isPushCreateButton &&
                      hasErrorIncorrectEncryptionPassword && (
                        <span className={styles.formError}>
                          {t(
                            getTranslationID(
                              "userListPage.message.encryptionPasswordCorrectError"
                            )
                          )}
                        </span>
                      )}
                    <span className={styles.formComment}>
                      {t(
                        getTranslationID(
                          "userListPage.label.encryptionPasswordTerm"
                        )
                      )}
                    </span>
                  </p>
                </dd>
                <dt>{t(getTranslationID("userListPage.label.prompt"))}</dt>
                <dd>
                  <label htmlFor="Prompt">
                    <input
                      type="checkbox"
                      className={styles.formCheck}
                      checked={user.prompt}
                      onChange={(e) => {
                        dispatch(
                          changeUpdatePrompt({
                            prompt: e.target.checked,
                          })
                        );
                      }}
                    />
                  </label>
                </dd>
              </div>
            )}

            <dt>{t(getTranslationID("userListPage.label.setting"))}</dt>
            <dd className="last">
              <p>
                <label htmlFor="edit_AutoRenew">
                  <input
                    type="checkbox"
                    id="edit_AutoRenew"
                    className={styles.formCheck}
                    checked={user.autoRenew}
                    onChange={(e) => {
                      dispatch(
                        changeUpdateAutoRenew({
                          autoRenew: e.target.checked,
                        })
                      );
                    }}
                  />
                  {t(getTranslationID("userListPage.label.autoRenew"))}
                </label>
              </p>
              <p>
                <label htmlFor="edit_Notification">
                  <input
                    type="checkbox"
                    id="edit_Notification"
                    className={styles.formCheck}
                    checked={user.notification}
                    onChange={(e) => {
                      dispatch(
                        changeUpdateNotification({
                          notification: e.target.checked,
                        })
                      );
                    }}
                  />
                  {t(getTranslationID("userListPage.label.notification"))}
                </label>
              </p>
            </dd>
            <dd className={`${styles.full} ${styles.alignCenter}`}>
              <input
                type="button"
                name="submit"
                value={t(getTranslationID("userListPage.label.editUser"))}
                className={`${styles.formSubmit} ${styles.marginBtm1} ${styles.isActive}`}
                onClick={onUpdateUser}
              />
              <img
                style={{ display: isLoading ? "inline" : "none" }}
                src={progress_activit}
                className={styles.icLoading}
                alt="Loading"
              />
            </dd>
          </dl>
        </form>
      </div>
    </div>
  );
};
