import React, { useCallback, useEffect } from "react";
import styles from "styles/app.module.scss";
import { useDispatch, useSelector } from "react-redux";
import {
  BACKUP_POPUP_LIST_SIZE,
  backupTasksAsync,
  changeBackupTaskAllCheched,
  changeBackupTaskChecked,
  listBackupPopupTasksAsync,
  selectBackupAllChecked,
  selectBackupTasks,
  selectBackupTotal,
  selectCurrentBackupPage,
  selectIsBackupListLoading,
  selectIsDownloading,
  selectTotalBackupPage,
} from "features/dictation";
import { AppDispatch } from "app/store";
import { getTranslationID } from "translation";
import { useTranslation } from "react-i18next";
import progress_activit from "../../assets/images/progress_activit.svg";
import close from "../../assets/images/close.svg";

interface BackupPopupProps {
  onClose: (isChanged: boolean) => void;
  isOpen: boolean;
}

export const BackupPopup: React.FC<BackupPopupProps> = (props) => {
  const { onClose, isOpen } = props;
  const dispatch: AppDispatch = useDispatch();
  const [t] = useTranslation();

  const isBackupListLoading = useSelector(selectIsBackupListLoading);
  const isDownloading = useSelector(selectIsDownloading);

  const backupTasks = useSelector(selectBackupTasks);

  const total = useSelector(selectBackupTotal);
  const totalPage = useSelector(selectTotalBackupPage);
  const currentPage = useSelector(selectCurrentBackupPage);

  const allChecked = useSelector(selectBackupAllChecked);

  // ポップアップを閉じる処理
  const closePopup = useCallback(() => {
    if (isDownloading) {
      return;
    }
    onClose(false);
  }, [onClose, isDownloading]);

  useEffect(() => {
    if (isOpen) {
      dispatch(listBackupPopupTasksAsync({ offset: 0 }));
    }
  }, [dispatch, isOpen]);

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

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

  // バックアップ処理
  const onBackup = useCallback(async () => {
    await dispatch(backupTasksAsync({ tasks: backupTasks }));

    // バックアップ処理の終了後、バックアップ対象タスク一覧を再取得する
    dispatch(listBackupPopupTasksAsync({ offset: 0 }));
  }, [dispatch, backupTasks]);

  // ページネーションの制御
  const getFirstPage = useCallback(() => {
    dispatch(listBackupPopupTasksAsync({ offset: 0 }));
  }, [dispatch]);

  const getLastPage = useCallback(() => {
    const lastPageOffset = (totalPage - 1) * BACKUP_POPUP_LIST_SIZE;
    dispatch(listBackupPopupTasksAsync({ offset: lastPageOffset }));
  }, [dispatch, totalPage]);

  const getPrevPage = useCallback(() => {
    const prevPageOffset = (currentPage - 2) * BACKUP_POPUP_LIST_SIZE;
    dispatch(listBackupPopupTasksAsync({ offset: prevPageOffset }));
  }, [dispatch, currentPage]);

  const getNextPage = useCallback(() => {
    const nextPageOffset = currentPage * BACKUP_POPUP_LIST_SIZE;
    dispatch(listBackupPopupTasksAsync({ offset: nextPageOffset }));
  }, [dispatch, currentPage]);

  return (
    <div className={`${styles.modal} ${isOpen ? styles.isShow : ""}`}>
      <div className={styles.modalBox}>
        <p className={styles.modalTitle}>
          {t(getTranslationID("dictationPage.label.fileBackup"))}
          <button
            type="button"
            onClick={closePopup}
            style={{ pointerEvents: isDownloading ? "none" : "auto" }}
          >
            <img src={close} className={styles.modalTitleIcon} alt="close" />
          </button>
        </p>
        <form className={styles.form}>
          <dl className={`${styles.formList} ${styles.hasbg}`}>
            <dd className={styles.full}>
              <div className={styles.tableWrap}>
                <table className={`${styles.table} ${styles.backup}`}>
                  <tr className={styles.tableHeader}>
                    <th className={styles.noLine}>
                      <input
                        type="checkbox"
                        checked={allChecked}
                        className={styles.formCheck}
                        onChange={(e) =>
                          dispatch(
                            changeBackupTaskAllCheched({
                              checked: e.target.checked,
                            })
                          )
                        }
                        disabled={isDownloading}
                      />
                    </th>
                    <th className={styles.noLine}>
                      {t(getTranslationID("dictationPage.label.jobNumber"))}
                    </th>
                    <th className={styles.noLine}>
                      {t(getTranslationID("dictationPage.label.status"))}
                    </th>
                    <th className={styles.noLine}>
                      {t(getTranslationID("dictationPage.label.fileName"))}
                    </th>
                    <th>
                      {t(
                        getTranslationID(
                          "dictationPage.label.transcriptionFinishedDate"
                        )
                      )}
                    </th>
                  </tr>

                  {!isBackupListLoading &&
                    backupTasks.map((task) => (
                      <tr key={task.audioFileId}>
                        <td>
                          <input
                            type="checkbox"
                            className={styles.formCheck}
                            checked={task.checked}
                            onChange={(e) => {
                              dispatch(
                                changeBackupTaskChecked({
                                  audioFileId: task.audioFileId,
                                  checked: e.target.checked,
                                })
                              );
                            }}
                            disabled={isDownloading}
                          />
                        </td>
                        <td>{task.jobNumber}</td>
                        <td>{task.status}</td>
                        <td>{task.fileName}</td>
                        <td>{task.transcriptionFinishedDate}</td>
                      </tr>
                    ))}
                  {isBackupListLoading && (
                    <img
                      style={{ position: "sticky" }}
                      src={progress_activit}
                      className={styles.icLoading}
                      alt="Loading"
                    />
                  )}
                </table>
              </div>

              {/** <!-- pagenation --> */}
              <div className={styles.pagenation}>
                <nav className={styles.pagenationNav}>
                  <span className={styles.pagenationTotal}>{`${total}  ${t(
                    getTranslationID("dictationPage.label.title")
                  )}`}</span>
                  {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                  <a
                    onClick={getFirstPage}
                    className={
                      !isBackupListLoading && currentPage !== 1
                        ? styles.isActive
                        : ""
                    }
                  >
                    «
                  </a>
                  {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                  <a
                    onClick={getPrevPage}
                    className={
                      !isBackupListLoading && currentPage !== 1
                        ? styles.isActive
                        : ""
                    }
                  >
                    ‹
                  </a>
                  {`${currentPage} of ${totalPage}`}
                  {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                  <a
                    onClick={getNextPage}
                    className={
                      !isBackupListLoading && currentPage < totalPage
                        ? styles.isActive
                        : ""
                    }
                  >
                    ›
                  </a>
                  {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                  <a
                    onClick={getLastPage}
                    className={
                      !isBackupListLoading && currentPage < totalPage
                        ? styles.isActive
                        : ""
                    }
                  >
                    »
                  </a>
                </nav>
              </div>
            </dd>
            <dd className={`${styles.full} ${styles.alignCenter}`}>
              <input
                type="button"
                name="submit"
                value={t(
                  getTranslationID("dictationPage.label.downloadForBackup")
                )}
                className={`${styles.formSubmit} ${styles.marginBtm1} ${
                  isDownloading || backupTasks.every((x) => !x.checked)
                    ? ""
                    : styles.isActive
                }`}
                onClick={onBackup}
              />
              {isDownloading && (
                <img
                  src={progress_activit}
                  className={styles.icLoading}
                  alt="Loading"
                />
              )}
            </dd>
          </dl>
        </form>
      </div>
    </div>
  );
};
