import { AppDispatch } from "app/store";
import {
  changeUploadFile,
  cleanupTemplate,
  listTemplateAsync,
  selectIsUploading,
  selectUploadFile,
  selectUploadFileError,
  uploadTemplateAsync,
} from "features/workflow/template";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import styles from "styles/app.module.scss";
import { getTranslationID } from "translation";
import close from "../../assets/images/close.svg";
import progress_activit from "../../assets/images/progress_activit.svg";

interface AddTemplateFilePopupProps {
  onClose: () => void;
}

export const AddTemplateFilePopup: React.FC<AddTemplateFilePopupProps> = (
  props: AddTemplateFilePopupProps
) => {
  const { onClose } = props;
  const [t] = useTranslation();
  const dispatch: AppDispatch = useDispatch();

  // 保存ボタンを押したかどうか
  const [isPushUploadButton, setIsPushUploadButton] = useState<boolean>(false);

  // アップロード対象のファイル情報
  const uploadFile = useSelector(selectUploadFile);
  // ファイルアップロード中かどうか
  const isUploading = useSelector(selectIsUploading);
  // ファイルのエラー
  const { hasErrorFileSize, hasErrorRequired } = useSelector(
    selectUploadFileError
  );

  // ブラウザのウィンドウが閉じられようとしている場合に発火するイベントハンドラ
  const handleBeforeUnload = (e: BeforeUnloadEvent) => {
    // テンプレートファイルアップロード中に閉じられようとしている場合、ダイアログを表示させる
    if (isUploading) {
      e.preventDefault();
      // ChromeではreturnValueが必要
      e.returnValue = "";
    }
  };

  // ファイルが選択されたときの処理
  const handleFileChange = useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      // 選択されたファイルを取得(複数選択されても先頭を取得)
      const file = event.target.files?.[0];

      // ファイルが選択されていれば、storeに保存
      if (file) {
        dispatch(changeUploadFile({ file }));
      }
      // 同名のファイルを選択した場合、onChangeが発火しないため、valueをクリアする
      event.target.value = "";
    },
    [dispatch]
  );

  // ファイルアップロード処理
  const handleUploadFile = useCallback(async () => {
    setIsPushUploadButton(true);
    // エラーチェックを実施
    if (hasErrorFileSize || hasErrorRequired) {
      return;
    }
    // ファイルアップロード処理
    const { meta } = await dispatch(uploadTemplateAsync());
    if (meta.requestStatus === "fulfilled") {
      onClose();
      dispatch(listTemplateAsync());
    }
  }, [dispatch, hasErrorFileSize, hasErrorRequired, onClose]);

  // コンポーネントがマウントされた時にイベントハンドラを登録する
  useEffect(() => {
    window.addEventListener("beforeunload", handleBeforeUnload);
    // コンポーネントがアンマウントされるときにイベントハンドラを解除する
    return () => {
      window.removeEventListener("beforeunload", handleBeforeUnload);
    };
  });

  useEffect(
    () => () => {
      // useEffectのreturnとしてcleanupAppsを実行することで、ポップアップのアンマウント時に初期化を行う
      dispatch(cleanupTemplate());
      setIsPushUploadButton(false);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    []
  );

  return (
    <div className={`${styles.modal} ${styles.isShow}`}>
      <div className={styles.modalBox}>
        <p className={styles.modalTitle}>
          {t(getTranslationID("templateFilePage.label.addTemplate"))}
          {/* 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={onClose}
          />
        </p>
        <form className={styles.form}>
          <dl className={`${styles.formList} ${styles.hasbg}`}>
            <dt className={styles.formTitle} />
            <dd
              className={`${styles.full} ${styles.alignCenter} ${styles.last}`}
            >
              <p className={styles.formFileName} style={{ marginRight: "5px" }}>
                {uploadFile?.name ??
                  t(getTranslationID("templateFilePage.label.notFileChosen"))}
              </p>

              <label htmlFor="template" className={styles.formFileButton}>
                {t(getTranslationID("templateFilePage.label.chooseFile"))}
                <input
                  type="file"
                  id="template"
                  className={`${styles.formInput} ${styles.isHide}`}
                  onChange={handleFileChange}
                />
              </label>
              {isPushUploadButton && hasErrorRequired && (
                <span className={`${styles.formError} ${styles.alignCenter}`}>
                  {t(getTranslationID("templateFilePage.label.fileEmptyError"))}
                </span>
              )}
              {isPushUploadButton && hasErrorFileSize && (
                <span
                  className={`${styles.formError} ${styles.alignCenter}`}
                  style={{ margin: "0px 30px 0px 30px" }}
                >
                  {t(getTranslationID("templateFilePage.label.fileSizeError"))}
                </span>
              )}
            </dd>
            <dd className={`${styles.full} ${styles.alignCenter}`}>
              <input
                type="button"
                name="submit"
                value={t(
                  getTranslationID("templateFilePage.label.addTemplate")
                )}
                onClick={handleUploadFile}
                className={`${styles.formSubmit} ${styles.marginBtm1} ${
                  !isUploading ? styles.isActive : ""
                }`}
              />
              {isUploading && (
                <img
                  src={progress_activit}
                  className={styles.icLoading}
                  alt="Loading"
                />
              )}
            </dd>
          </dl>
        </form>
      </div>
    </div>
  );
};
