import { AppDispatch } from "app/store";
import {
  selectAdminName,
  selectAllDealers,
  selectCompany,
  selectCountry,
  selectDealer,
  selectEmail,
  selectInputValidationErrors,
  selectSameCountryDealers,
} from "features/signup/selectors";
import {
  changeAdminName,
  changeCompany,
  changeCountry,
  changeDealer,
  changeEmail,
  changePageState,
  changePassword,
} from "features/signup/signupSlice";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
import { getTranslationID } from "translation";
import styles from "styles/app.module.scss";
import { getDealersAsync } from "features/signup/operations";
import { LANGUAGE_LIST } from "features/top/constants";
import { openSnackbar } from "features/ui";
import { COUNTRY_LIST } from "./constants";

const SignupInput: React.FC = (): JSX.Element => {
  const dispatch: AppDispatch = useDispatch();
  const [t, i18n] = useTranslation();
  const { search } = useLocation();
  const navigate = useNavigate();
  const [isPasswordHide, setIsPasswordHide] = useState<boolean>(true);
  const [isOpenPolicy, setIsOpenPolicy] = useState<boolean>(false);
  const [isAgreePolicy, setIsAgreePolicy] = useState<boolean>(false);
  const [isPushCreateButton, setIsPushCreateButton] = useState<boolean>(false);
  const {
    hasErrorEmptyAdminName,
    hasErrorEmptyCompany,
    hasErrorEmptyCountry,
    hasErrorEmptyEmail,
    hasErrorEmptyPassword,
    hasErrorIncorrectEmail,
    hasErrorIncorrectPassword,
  } = useSelector(selectInputValidationErrors);

  const onSubmit = useCallback(() => {
    if (
      hasErrorEmptyAdminName ||
      hasErrorEmptyCompany ||
      hasErrorEmptyCountry ||
      hasErrorEmptyEmail ||
      hasErrorEmptyPassword ||
      hasErrorIncorrectEmail ||
      hasErrorIncorrectPassword
    ) {
      return;
    }
    dispatch(changePageState({ pageState: "confirm" }));
  }, [
    dispatch,
    hasErrorEmptyAdminName,
    hasErrorEmptyCompany,
    hasErrorEmptyCountry,
    hasErrorEmptyEmail,
    hasErrorEmptyPassword,
    hasErrorIncorrectEmail,
    hasErrorIncorrectPassword,
  ]);

  const allDealers = useSelector(selectAllDealers);
  const dealers = useSelector(selectSameCountryDealers);

  const company = useSelector(selectCompany);
  const country = useSelector(selectCountry);
  const dealer = useSelector(selectDealer);
  const adminName = useSelector(selectAdminName);
  const email = useSelector(selectEmail);

  // 入力画面の初期化時の処理
  useEffect(() => {
    dispatch(getDealersAsync());
  }, [dispatch]);

  useEffect(() => {
    // 外部のWebサイトからの遷移時にURLのパラメータを取得
    // 以下のようなURLで遷移してきた場合に、Dealerと言語を変更する
    // https://xxx/signup?dealer=1&language=en
    // dealer={account_id（第四階層のアカウントID）} でDealerを指定
    // language={language(en/de/fr/es)} で言語を指定
    const query = new URLSearchParams(search);
    const paramDealer = query.get("dealer");
    const language = query.get("language");

    // URLで言語が指定されていたら言語を変更
    if (language && LANGUAGE_LIST.map((x) => x.value).includes(language)) {
      i18n.changeLanguage(language);
      // 既にcookieに選択言語があれば削除
      document.cookie = "language=; max-age=0";
      // cookieの期限は1年
      document.cookie = `language=${language}; max-age=31536000`;
    }

    // Dealerが取得できていない場合は何もしない
    if (allDealers.length === 0) {
      return;
    }

    // URLでDealerが指定されていたら、そのDealerを選択（国も選択したDealerの国に変更）
    const urlDealer = allDealers.find(
      (x) => x.id === parseInt(paramDealer ?? "", 10)
    );
    if (urlDealer) {
      dispatch(changeCountry({ country: urlDealer.country }));
      dispatch(changeDealer({ dealer: urlDealer.id }));
    } else if (paramDealer) {
      // URLでDealerが指定されていたが、存在しない場合はメッセージを表示
      dispatch(
        openSnackbar({
          level: "error",
          message: t(
            getTranslationID("signupPage.message.dealerNotFoundError")
          ),
        })
      );
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [i18n, dispatch, search, allDealers]);

  return (
    <div className={styles.wrap}>
      <header />
      <main className={styles.main}>
        <div className={styles.mainSmall}>
          <div>
            <h1 className={styles.marginBtm1}>
              {t(getTranslationID("signupPage.text.title"))}
            </h1>
            <p className={styles.marginBtm2}>
              {t(getTranslationID("signupPage.text.pageExplanation"))}
            </p>
          </div>
          <section>
            <form>
              <dl className={`${styles.formList} ${styles.hasbg}`}>
                <dt className={` ${styles.formTitle} ${styles.marginBtm0}`}>
                  {t(getTranslationID("signupPage.text.accountInfoTitle"))}
                </dt>
                <dt> {t(getTranslationID("signupPage.label.company"))}</dt>
                <dd>
                  <input
                    type="text"
                    size={64}
                    autoComplete="organization"
                    className={`${styles.formInput} ${
                      isPushCreateButton &&
                      hasErrorEmptyCompany &&
                      styles.isError
                    }`}
                    onChange={(e) => {
                      dispatch(changeCompany({ company: e.target.value }));
                    }}
                    value={company}
                  />
                  {isPushCreateButton && hasErrorEmptyCompany && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID("signupPage.message.inputEmptyError")
                      )}
                    </span>
                  )}
                </dd>
                <dt> {t(getTranslationID("signupPage.label.country"))}</dt>
                <dd>
                  <select
                    className={`${styles.formInput} ${
                      isPushCreateButton &&
                      hasErrorEmptyCountry &&
                      styles.isError
                    }`}
                    onChange={(event) => {
                      dispatch(changeCountry({ country: event.target.value }));
                    }}
                    value={
                      COUNTRY_LIST.find((x) => x.value === country)?.value ?? ""
                    }
                  >
                    {COUNTRY_LIST.map((x) => (
                      <option key={x.value} value={x.value}>
                        {x.label}
                      </option>
                    ))}
                  </select>
                  {isPushCreateButton && hasErrorEmptyCountry && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID("signupPage.message.inputEmptyError")
                      )}
                    </span>
                  )}
                  <span className={styles.formComment}>
                    {t(getTranslationID("signupPage.text.countryExplanation"))}
                  </span>
                </dd>
                <dt> {t(getTranslationID("signupPage.label.dealer"))}</dt>
                <dd>
                  <select
                    className={styles.formInput}
                    onChange={(event) => {
                      dispatch(
                        changeDealer({
                          dealer: parseInt(event.target.value, 10),
                        })
                      );
                    }}
                    value={dealers.find((x) => x.id === dealer)?.id ?? NaN}
                  >
                    {[
                      {
                        id: NaN,
                        country: "",
                        name: "Select dealer",
                      },
                      ...dealers,
                    ].map((x) => (
                      <option key={x.id} value={x.id}>
                        {x.name}
                      </option>
                    ))}
                  </select>
                  <span className={styles.formComment}>
                    {t(getTranslationID("signupPage.text.dealerExplanation"))}
                  </span>
                </dd>
                <dt className={`  ${styles.formTitle} ${styles.marginBtm0}`}>
                  {t(getTranslationID("signupPage.text.adminInfoTitle"))}
                </dt>
                <dt> {t(getTranslationID("signupPage.label.adminName"))}</dt>
                <dd>
                  <input
                    type="text"
                    size={256}
                    autoComplete="organization"
                    className={`${styles.formInput} ${
                      isPushCreateButton &&
                      hasErrorEmptyAdminName &&
                      styles.isError
                    }`}
                    onChange={(e) => {
                      dispatch(changeAdminName({ adminName: e.target.value }));
                    }}
                    value={adminName}
                  />
                  {isPushCreateButton && hasErrorEmptyAdminName && (
                    <span className={styles.formError}>
                      {" "}
                      {t(
                        getTranslationID("signupPage.message.inputEmptyError")
                      )}
                    </span>
                  )}
                </dd>
                <dt> {t(getTranslationID("signupPage.label.email"))}</dt>
                <dd>
                  <input
                    type="text"
                    size={64}
                    autoComplete="organization"
                    className={`${styles.formInput}
                    ${
                      isPushCreateButton &&
                      (hasErrorEmptyEmail || hasErrorIncorrectEmail) &&
                      styles.isError
                    }`}
                    onChange={(e) => {
                      dispatch(changeEmail({ email: e.target.value }));
                    }}
                    value={email}
                  />
                  {isPushCreateButton && hasErrorEmptyEmail && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID("signupPage.message.inputEmptyError")
                      )}
                    </span>
                  )}
                  {isPushCreateButton && hasErrorIncorrectEmail && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID(
                          "signupPage.message.emailIncorrectError"
                        )
                      )}
                    </span>
                  )}
                </dd>
                <dt> {t(getTranslationID("signupPage.label.password"))}</dt>
                <dd className={styles.marginBtm1}>
                  <input
                    type={isPasswordHide ? "password" : "text"}
                    size={64}
                    className={`${styles.formInput} ${styles.password}
                    ${
                      isPushCreateButton &&
                      (hasErrorIncorrectPassword || hasErrorEmptyPassword) &&
                      styles.isError
                    }
                    `}
                    onChange={(e) => {
                      dispatch(changePassword({ password: e.target.value }));
                    }}
                  />
                  <span
                    className={styles.formIconEye}
                    onClick={() => {
                      setIsPasswordHide(!isPasswordHide);
                    }}
                    onKeyDown={() => {
                      setIsPasswordHide(!isPasswordHide);
                    }}
                    role="button"
                    tabIndex={0}
                    aria-label="IconEye"
                  />
                  {isPushCreateButton && hasErrorEmptyPassword && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID("signupPage.message.inputEmptyError")
                      )}
                    </span>
                  )}
                  {isPushCreateButton && hasErrorIncorrectPassword && (
                    <span className={styles.formError}>
                      {t(
                        getTranslationID(
                          "signupPage.message.passwordIncorrectError"
                        )
                      )}
                    </span>
                  )}
                  {/** XXX: 改行に対応するためにここでstyleを当てている。
                   * デザインを修正していただいたらもとに戻す
                   */}
                  <span
                    style={{ whiteSpace: "pre-line" }}
                    className={styles.formComment}
                  >
                    {t(getTranslationID("signupPage.text.passwordTerms"))}
                  </span>
                </dd>
                <dd className={`${styles.full} ${styles.alignCenter}`}>
                  <a
                    href="/"
                    target="_blank"
                    className={styles.linkTx}
                    onClick={() => {
                      setIsOpenPolicy(true);
                    }}
                  >
                    {t(getTranslationID("signupPage.label.termsLink"))}
                  </a>{" "}
                  {t(getTranslationID("signupPage.label.termsLinkFor"))} <br />
                  <label htmlFor="check-box">
                    <input
                      id="check-box"
                      type="checkbox"
                      className={styles.formCheck}
                      disabled={!isOpenPolicy}
                      onChange={(e) => {
                        setIsAgreePolicy(e.target.checked);
                      }}
                    />
                    {t(getTranslationID("signupPage.label.termsCheckBox"))}
                  </label>
                </dd>
                <dd className={` ${styles.full} ${styles.alignCenter}`}>
                  <input
                    type="button"
                    name="submit"
                    value={t(
                      getTranslationID("signupPage.label.createAccountButton")
                    )}
                    className={`${styles.formSubmit} 
                    ${isAgreePolicy && styles.isActive}
                    ${styles.marginBtm0}`}
                    onClick={() => {
                      setIsPushCreateButton(true);
                      onSubmit();
                    }}
                  />
                  <br />
                  <input
                    type="button"
                    name="cancel"
                    value={t(getTranslationID("common.label.cancel"))}
                    className={styles.formButtonTx}
                    onClick={() => {
                      navigate("/");
                    }}
                  />
                </dd>
              </dl>
            </form>
          </section>
        </div>
      </main>
    </div>
  );
};

export default SignupInput;
