import {
  useEffect,
  useState
} from "react";

import {
  useLocation,
  useNavigate
} from "react-router-dom";

import {
  useAdminAuth
} from "../../context/AdminAuthContext";

const AdminLogin = () => {
  const navigate =
    useNavigate();

  const location =
    useLocation();

  const {
    login,
    isAuthenticated,
    loading
  } = useAdminAuth();

  const [
    identifier,
    setIdentifier
  ] = useState("");

  const [
    password,
    setPassword
  ] = useState("");

  const [
    showPassword,
    setShowPassword
  ] = useState(false);

  const [
    submitting,
    setSubmitting
  ] = useState(false);

  const [error, setError] =
    useState("");

  const [
    fieldErrors,
    setFieldErrors
  ] = useState({});

  useEffect(() => {
    if (
      !loading &&
      isAuthenticated
    ) {
      navigate(
        "/admin/dashboard",
        {
          replace: true
        }
      );
    }
  }, [
    loading,
    isAuthenticated,
    navigate
  ]);

  const clearFieldError = (
    fieldName
  ) => {
    setFieldErrors(
      (currentErrors) => {
        const nextErrors = {
          ...currentErrors
        };

        delete nextErrors[
          fieldName
        ];

        return nextErrors;
      }
    );
  };

  const handleSubmit =
    async (event) => {
      event.preventDefault();

      const localErrors = {};

      if (!identifier.trim()) {
        localErrors.identifier =
          "Enter your username or email address.";
      }

      if (!password) {
        localErrors.password =
          "Enter your password.";
      }

      if (
        Object.keys(
          localErrors
        ).length > 0
      ) {
        setFieldErrors(
          localErrors
        );

        setError(
          "Enter your administrator login details."
        );

        return;
      }

      try {
        setSubmitting(true);
        setError("");
        setFieldErrors({});

        await login({
          identifier:
            identifier.trim(),

          password
        });

        const destination =
          location.state?.from &&
          location.state.from !==
            "/admin/login"
            ? location.state.from
            : "/admin/dashboard";

        navigate(
          destination,
          {
            replace: true
          }
        );
      } catch (requestError) {
        const responseData =
          requestError.response?.data;

        setError(
          responseData?.message ||
            requestError.message ||
            "Unable to sign in to the administrator portal."
        );

        setFieldErrors(
          responseData?.errors || {}
        );
      } finally {
        setSubmitting(false);
      }
    };

  return (
    <main className="admin-login-page">
      <section className="admin-login-brand">
        <div className="admin-login-brand__content">
          <span className="admin-system-label">
            CAGD
          </span>

          <h1>
            Staff Records Management System
          </h1>

          <p>
            Human Resource Administration and
            Staff Records Review Portal
          </p>

          <div className="admin-security-note">
            <strong>
              Authorised access only
            </strong>

            <span>
              All administrator activity is
              recorded for security and audit
              purposes.
            </span>
          </div>
        </div>
      </section>

      <section className="admin-login-section">
        <div className="admin-login-card">
          <div className="admin-login-card__heading">
            <span>
              Administration Portal
            </span>

            <h2>
              Sign in to continue
            </h2>

            <p>
              Enter your administrator
              username or email address.
            </p>
          </div>

          {error && (
            <div
              className="form-alert form-alert--error"
              role="alert"
            >
              {error}
            </div>
          )}

          <form
            onSubmit={
              handleSubmit
            }
            className="admin-login-form"
          >
            <div className="form-group">
              <label htmlFor="admin_identifier">
                Username or Email
              </label>

              <input
                id="admin_identifier"
                type="text"
                value={identifier}
                onChange={(event) => {
                  setIdentifier(
                    event.target.value
                  );

                  setError("");

                  clearFieldError(
                    "identifier"
                  );
                }}
                disabled={submitting}
                autoComplete="username"
                autoFocus
                placeholder="Enter username or email"
              />

              {fieldErrors
                .identifier && (
                <small className="field-error">
                  {
                    fieldErrors
                      .identifier
                  }
                </small>
              )}
            </div>

            <div className="form-group">
              <label htmlFor="admin_password">
                Password
              </label>

              <div className="admin-password-field">
                <input
                  id="admin_password"
                  type={
                    showPassword
                      ? "text"
                      : "password"
                  }
                  value={password}
                  onChange={(event) => {
                    setPassword(
                      event.target.value
                    );

                    setError("");

                    clearFieldError(
                      "password"
                    );
                  }}
                  disabled={submitting}
                  autoComplete="current-password"
                  placeholder="Enter password"
                />

                <button
                  type="button"
                  className="admin-password-toggle"
                  onClick={() =>
                    setShowPassword(
                      (current) =>
                        !current
                    )
                  }
                  disabled={submitting}
                >
                  {showPassword
                    ? "Hide"
                    : "Show"}
                </button>
              </div>

              {fieldErrors
                .password && (
                <small className="field-error">
                  {
                    fieldErrors
                      .password
                  }
                </small>
              )}
            </div>

            <button
              type="submit"
              className="primary-button admin-login-button"
              disabled={submitting}
            >
              {submitting
                ? "Signing in..."
                : "Sign in"}
            </button>
          </form>

          <p className="admin-login-support">
            Contact the system administrator
            when you cannot access your
            account.
          </p>
        </div>
      </section>
    </main>
  );
};

export default AdminLogin;