import React, { useCallback, useEffect, useState } from "react";
import { AppDispatch } from "app/store";
import progress_activit from "assets/images/progress_activit.svg";
import {
  addAssignee,
  removeAssignee,
  changeAuthor,
  changeTemplate,
  changeWorktype,
  clearWorkflow,
  selectIsAddLoading,
  selectWorkflowAssinee,
  selectWorkflowError,
  selectWorkflowRelations,
  selectSelectedWorkflow,
  selectAuthorId,
  selectWorktypeId,
  setAssignees,
  selectTemplateId,
} from "features/workflow";
import {
  getworkflowRelationsAsync,
  listWorkflowAsync,
  updateWorkflowAsync,
} from "features/workflow/operations";
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";

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

export const EditWorkflowPopup: React.FC<EditWorkflowPopupProps> = (
  props
): JSX.Element => {
  const { onClose } = props;
  const dispatch: AppDispatch = useDispatch();
  const [t] = useTranslation();
  // 保存ボタンを押したかどうか
  const [isPushEditButton, setIsPushEditButton] = useState<boolean>(false);

  const workflow = useSelector(selectSelectedWorkflow);
  const authorId = useSelector(selectAuthorId);
  const worktypeId = useSelector(selectWorktypeId);
  const templateId = useSelector(selectTemplateId);

  const workflowRelations = useSelector(selectWorkflowRelations);
  const { poolAssignees, selectedAssignees } = useSelector(
    selectWorkflowAssinee
  );
  const isLoading = useSelector(selectIsAddLoading);
  const { hasAuthorIdEmptyError, hasSelectedWorkflowAssineeEmptyError } =
    useSelector(selectWorkflowError);
  useEffect(() => {
    dispatch(getworkflowRelationsAsync());
    // ポップアップのアンマウント時に初期化を行う
    return () => {
      dispatch(clearWorkflow());
      setIsPushEditButton(false);
    };
  }, [dispatch]);

  useEffect(() => {
    dispatch(changeAuthor({ authorId: workflow?.author?.id }));
    dispatch(changeWorktype({ worktypeId: workflow?.worktype?.id }));
    dispatch(changeTemplate({ templateId: workflow?.template?.id }));
    dispatch(setAssignees({ assignees: workflow?.typists ?? [] }));
  }, [dispatch, workflow]);

  const changeWorktypeId = useCallback(
    (target: string) => {
      // 空文字の場合はundefinedをdispatchする
      if (target === "") {
        dispatch(changeWorktype({ worktypeId: undefined }));
      } else if (!Number.isNaN(Number(target))) {
        dispatch(changeWorktype({ worktypeId: Number(target) }));
      }
    },
    [dispatch]
  );

  const changeTemplateId = useCallback(
    (target: string) => {
      // 空文字の場合はundefinedをdispatchする
      if (target === "") {
        dispatch(changeTemplate({ templateId: undefined }));
      } else if (!Number.isNaN(Number(target))) {
        dispatch(changeTemplate({ templateId: Number(target) }));
      }
    },
    [dispatch]
  );

  const changeAuthorId = useCallback(
    (target: string) => {
      if (!Number.isNaN(target)) {
        dispatch(changeAuthor({ authorId: Number(target) }));
      }
    },
    [dispatch]
  );

  // 保存ボタン押下時の処理
  const handleSave = useCallback(async () => {
    setIsPushEditButton(true);
    // エラーチェック
    if (hasAuthorIdEmptyError || hasSelectedWorkflowAssineeEmptyError) {
      return;
    }
    const { meta } = await dispatch(updateWorkflowAsync());
    if (meta.requestStatus === "fulfilled") {
      onClose();
      dispatch(listWorkflowAsync());
    }
  }, [
    dispatch,
    hasAuthorIdEmptyError,
    hasSelectedWorkflowAssineeEmptyError,
    onClose,
  ]);

  return (
    <div className={`${styles.modal} ${styles.isShow}`}>
      <div className={styles.modalBox}>
        <p className={styles.modalTitle}>
          {t(getTranslationID("workflowPage.label.editRoutingRule"))}
          {/* 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} />
            <dt>{t(getTranslationID("workflowPage.label.authorID"))}</dt>
            <dd>
              <select
                className={styles.formInput}
                value={authorId}
                onChange={(e) => {
                  changeAuthorId(e.target.value);
                }}
              >
                <option value="" hidden>
                  {`-- ${t(
                    getTranslationID("workflowPage.label.selectAuthor")
                  )} --`}
                </option>
                {workflowRelations?.authors.map((author) => (
                  <option key={author.authorId} value={author.id}>
                    {author.authorId}
                  </option>
                ))}
              </select>
              {isPushEditButton && hasAuthorIdEmptyError && (
                <span className={styles.formError}>
                  {t(getTranslationID("workflowPage.message.inputEmptyError"))}
                </span>
              )}
            </dd>
            <dt className={styles.overLine}>
              {t(getTranslationID("workflowPage.label.worktypeOptional"))}
            </dt>
            <dd>
              <select
                className={styles.formInput}
                value={worktypeId}
                onChange={(e) => {
                  changeWorktypeId(e.target.value);
                }}
              >
                <option value="" hidden>
                  {`-- ${t(
                    getTranslationID("workflowPage.label.selectWorktypeId")
                  )} --`}
                </option>
                <option value="">
                  {`-- ${t(getTranslationID("common.label.notSelected"))} --`}
                </option>
                {workflowRelations?.worktypes.map((worktype) => (
                  <option key={worktype.id} value={worktype.id}>
                    {worktype.worktypeId}
                  </option>
                ))}
              </select>
            </dd>
            <dt className={styles.formTitle}>
              {t(getTranslationID("typistGroupSetting.label.transcriptionist"))}
            </dt>
            <dd className={`${styles.formChange} ${styles.last}`}>
              <ul className={styles.chooseMember}>
                <li className={styles.changeTitle}>
                  {t(getTranslationID("workflowPage.label.selected"))}
                </li>
                {selectedAssignees?.map((x) => {
                  const key = `${x.typistName}_${
                    x.typistUserId ?? x.typistGroupId
                  }`;
                  return (
                    <li key={key}>
                      <input
                        type="checkbox"
                        className={styles.formCheck}
                        value={x.typistName}
                        id={key}
                        checked
                        onClick={() => {
                          dispatch(removeAssignee({ assignee: x }));
                        }}
                      />
                      <label htmlFor={key} title="Remove">
                        {x.typistName}
                      </label>
                    </li>
                  );
                })}
              </ul>
              <p />
              <ul className={styles.holdMember}>
                <li className={styles.changeTitle}>
                  {t(getTranslationID("workflowPage.label.pool"))}
                </li>
                {poolAssignees?.map((x) => {
                  const key = `${x.typistName}_${
                    x.typistUserId ?? x.typistGroupId
                  }`;
                  return (
                    <li key={key}>
                      <input
                        type="checkbox"
                        className={styles.formCheck}
                        value={x.typistName}
                        id={key}
                        onClick={() => dispatch(addAssignee({ assignee: x }))}
                      />
                      <label htmlFor={key} title="Add">
                        {x.typistName}
                      </label>
                    </li>
                  );
                })}
              </ul>
              {isPushEditButton && hasSelectedWorkflowAssineeEmptyError && (
                <span
                  className={styles.formError}
                  style={{ margin: "0px 30px 0px 30px" }}
                >
                  {t(
                    getTranslationID(
                      "workflowPage.message.selectedTypistEmptyError"
                    )
                  )}
                </span>
              )}
            </dd>
            <dt className={styles.overLine}>
              {t(getTranslationID("workflowPage.label.templateOptional"))}
            </dt>
            <dd className={styles.last}>
              <select
                className={styles.formInput}
                value={templateId}
                onChange={(e) => {
                  changeTemplateId(e.target.value);
                }}
              >
                <option value="" hidden>
                  {`-- ${t(
                    getTranslationID("workflowPage.label.selectTemplate")
                  )} --`}
                </option>
                <option value="">
                  {`-- ${t(getTranslationID("common.label.notSelected"))} --`}
                </option>
                {workflowRelations?.templates.map((template) => (
                  <option
                    key={`${template.name}_${template.id}`}
                    value={template.id}
                  >
                    {template.name}
                  </option>
                ))}
              </select>
            </dd>
            <dd className={`${styles.full} ${styles.alignCenter}`}>
              <input
                type="button"
                value={t(getTranslationID("common.label.save"))}
                className={`${styles.formSubmit} ${styles.marginBtm1} ${
                  !isLoading ? styles.isActive : ""
                }`}
                onClick={handleSave}
              />
              {isLoading && (
                <img
                  src={progress_activit}
                  className={styles.icLoading}
                  alt="Loading"
                />
              )}
            </dd>
          </dl>
        </form>
      </div>
    </div>
  );
};
