import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import styles from "styles/app.module.scss";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch } from "app/store";
import { getTranslationID } from "translation";
import {
  changeOptionItems,
  cleanupWorktype,
  editOptionItemsAsync,
  getOptionItemsAsync,
  selectHasErrorOptionItems,
  selectIsOptionItemsLoading,
  selectOptionItems,
} from "features/workflow/worktype";
import { OPTION_ITEMS_DEFAULT_VALUE_TYPE } from "features/workflow/worktype/constants";
import { isOptionItemDefaultValueType } from "features/workflow/worktype/types";
import { isErrorObject } from "common/errors";
import close from "../../assets/images/close.svg";
import progress_activit from "../../assets/images/progress_activit.svg";

// popupのpropsの型定義
interface EditOptionItemsPopupProps {
  onClose: () => void;
  isOpen: boolean;
}

export const EditOptionItemsPopup: React.FC<EditOptionItemsPopupProps> = (
  props: EditOptionItemsPopupProps
): JSX.Element => {
  const { onClose, isOpen } = props;
  const dispatch: AppDispatch = useDispatch();
  // optionItemsを取得
  const optionItems = useSelector(selectOptionItems);
  const isLoading = useSelector(selectIsOptionItemsLoading);
  const [t] = useTranslation();

  const closePopup = useCallback(() => {
    onClose();
    setCanDisplay(false);
    dispatch(cleanupWorktype());
    setIsPushSaveButton(false);
  }, [onClose, dispatch]);

  // 今の入力状態のエラー有無
  const { hasIncorrectPatternOptionItems, hasInvalidOptionItems } = useSelector(
    selectHasErrorOptionItems
  );
  // 保存ボタンを押したかどうか
  const [isPushSaveButton, setIsPushSaveButton] = useState<boolean>(false);

  // ポップアップを表示するかどうか
  const [canDisplay, setCanDisplay] = useState<boolean>(false);

  useEffect(() => {
    (async () => {
      // optionItems取得
      if (isOpen) {
        const { meta, payload } = await dispatch(getOptionItemsAsync());

        if (
          meta.requestStatus === "rejected" &&
          isErrorObject(payload) &&
          payload.error.code === "E011003"
        ) {
          // WorkTypeが存在しない場合はポップアップを閉じる
          closePopup();
        } else {
          setCanDisplay(true);
        }
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dispatch, isOpen]);

  const onChangeOptionItem = useCallback(
    (optionItem: {
      defaultValueType: string;
      id: number;
      itemLabel: string;
      initialValue: string;
    }) => {
      const { defaultValueType } = optionItem;
      if (isOptionItemDefaultValueType(defaultValueType)) {
        dispatch(
          changeOptionItems({ optionItem: { ...optionItem, defaultValueType } })
        );
      }
    },
    [dispatch]
  );

  // optionItemsの更新
  const onSubmit = useCallback(async () => {
    setIsPushSaveButton(true);
    if (hasIncorrectPatternOptionItems || hasInvalidOptionItems) {
      return;
    }

    // optionItemsの更新API呼び出し
    const { meta } = await dispatch(editOptionItemsAsync());
    if (meta.requestStatus === "fulfilled") {
      closePopup();
    }
  }, [
    closePopup,
    dispatch,
    hasIncorrectPatternOptionItems,
    hasInvalidOptionItems,
  ]);

  return (
    <div
      className={`${styles.modal} ${isOpen && canDisplay ? styles.isShow : ""}`}
    >
      <div className={styles.modalBox}>
        <p className={styles.modalTitle}>
          {t(getTranslationID("worktypeIdSetting.label.optionItem"))}
          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions */}
          <img
            src={close}
            className={styles.modalTitleIcon}
            alt="close"
            onClick={closePopup}
          />
        </p>
        <form className={styles.form}>
          <dl className={`${styles.formList} ${styles.hasbg}`}>
            <dd className={styles.full}>
              <div className={styles.tableWrap}>
                <table className={styles.table}>
                  <tr className={styles.tableHeader}>
                    <th className={styles.noLine}>
                      {t(getTranslationID("worktypeIdSetting.label.itemLabel"))}
                    </th>
                    <th className={styles.noLine}>
                      {t(
                        getTranslationID("worktypeIdSetting.label.defaultValue")
                      )}
                    </th>
                    <th>
                      {t(
                        getTranslationID("worktypeIdSetting.label.initialValue")
                      )}
                    </th>
                  </tr>
                  {optionItems?.map((item) => (
                    <tr key={`optionItem_${item.id}`}>
                      <td>
                        <input
                          type="text"
                          maxLength={16}
                          name="itemLabel"
                          value={item.itemLabel}
                          className={styles.formInput}
                          onChange={(e) => {
                            const { value } = e.target;
                            // optionItemsの更新
                            const newOptionItem = {
                              ...item,
                              itemLabel: value,
                            };
                            onChangeOptionItem(newOptionItem);
                          }}
                        />
                      </td>
                      <td>
                        <select
                          name="defaultValueType"
                          className={styles.formInput}
                          value={item.defaultValueType}
                          onChange={(e) => {
                            const { value } = e.target;
                            // optionItemsの更新
                            const newOptionItem = {
                              ...item,
                              defaultValueType: value,
                            };
                            onChangeOptionItem(newOptionItem);
                          }}
                        >
                          <option
                            value={OPTION_ITEMS_DEFAULT_VALUE_TYPE.DEFAULT}
                          >
                            {t(
                              getTranslationID(
                                "worktypeIdSetting.label.default"
                              )
                            )}
                          </option>
                          <option value={OPTION_ITEMS_DEFAULT_VALUE_TYPE.BLANK}>
                            {t(
                              getTranslationID("worktypeIdSetting.label.blank")
                            )}
                          </option>
                          <option
                            value={OPTION_ITEMS_DEFAULT_VALUE_TYPE.LAST_INPUT}
                          >
                            {t(
                              getTranslationID(
                                "worktypeIdSetting.label.lastInput"
                              )
                            )}
                          </option>
                        </select>
                      </td>
                      <td>
                        {item.defaultValueType ===
                        OPTION_ITEMS_DEFAULT_VALUE_TYPE.DEFAULT ? (
                          <input
                            type="text"
                            maxLength={20}
                            name="initialValue"
                            value={item.initialValue}
                            className={styles.formInput}
                            onChange={(e) => {
                              const { value } = e.target;
                              // optionItemsの更新
                              const newOptionItem = {
                                ...item,
                                initialValue: value,
                              };
                              onChangeOptionItem(newOptionItem);
                            }}
                          />
                        ) : (
                          "-"
                        )}
                      </td>
                    </tr>
                  ))}
                </table>
                {isPushSaveButton && hasInvalidOptionItems && (
                  <span className={`${styles.formError} ${styles.alignCenter}`}>
                    {t(
                      getTranslationID(
                        "worktypeIdSetting.message.optionItemInvalidError"
                      )
                    )}
                  </span>
                )}
                {isPushSaveButton && hasIncorrectPatternOptionItems && (
                  <span className={`${styles.formError} ${styles.alignCenter}`}>
                    {t(
                      getTranslationID(
                        "worktypeIdSetting.message.optionItemIncorrectError"
                      )
                    )}
                  </span>
                )}
                <span
                  style={{ display: "block" }}
                  className={`${styles.formComment} ${styles.alignCenter}`}
                >
                  {t(
                    getTranslationID("worktypeIdSetting.label.optionItemTerms")
                  )}
                </span>
              </div>
            </dd>
            <dd className={`${styles.full} ${styles.alignCenter}`}>
              <input
                type="button"
                name="submit"
                value={t(getTranslationID("common.label.save"))}
                className={`${styles.formSubmit} ${styles.marginBtm1} ${
                  optionItems !== undefined && optionItems.length > 0
                    ? styles.isActive
                    : ""
                }`}
                onClick={onSubmit}
              />
              {isLoading && (
                <img
                  src={progress_activit}
                  className={styles.icLoading}
                  alt="Loading"
                />
              )}
            </dd>
          </dl>
        </form>
      </div>
    </div>
  );
};
