(function initPortfolioAccountSettings(global) {
  const {
    INVALID_CREDENTIALS_MESSAGE,
    LOGIN_TECHNICAL_ERROR_CODE,
    VALIDATION_CODES,
    readAuthToken
  } = global.PortfolioAppConfig;

  const {
    getValidationMessage,
    clearSessionStorage
  } = global.PortfolioApp;

  const {
    hashPasswordWithArgon2,
    hashPasswordWithServerParameters
  } = global.PortfolioHashing || {};

  const sharedComponents = global.PortfolioSharedComponents || {};
  const BlockingScreenLoader = sharedComponents.BlockingScreenLoader;

  const PASSWORD_CHANGED_MESSAGE_KEY = 'portfolio-auth-message';

  function readLoggedInEmail() {
    const token = readAuthToken();
    if (typeof token !== 'string' || !token) {
      return '';
    }

    try {
      const parts = token.split('.');
      if (parts.length < 2) {
        return '';
      }

      const encodedPayload = parts[1].replace(/-/g, '+').replace(/_/g, '/');
      const paddedPayload = encodedPayload + '='.repeat((4 - (encodedPayload.length % 4)) % 4);
      const payload = JSON.parse(window.atob(paddedPayload));
      return typeof payload.email === 'string' ? payload.email.trim() : '';
    } catch (error) {
      return '';
    }
  }

  function validateChangePasswordFields(values) {
    const errors = {};
    const currentPassword = values.currentPassword || '';
    const newPassword = values.newPassword || '';
    const confirmNewPassword = values.confirmNewPassword || '';

    if (!currentPassword) {
      errors.currentPassword = 'Current password is required.';
    }

    if (!newPassword) {
      errors.newPassword = 'New password is required.';
    } else if (currentPassword && newPassword === currentPassword) {
      errors.newPassword = 'New password must be different from your current password.';
    }

    if (!confirmNewPassword) {
      errors.confirmNewPassword = 'Please confirm your new password.';
    } else if (newPassword && confirmNewPassword && newPassword !== confirmNewPassword) {
      errors.confirmNewPassword = 'Passwords do not match.';
    }

    return errors;
  }

  function ChangePasswordPanel({ navigate }) {
    const [formValues, setFormValues] = React.useState({ currentPassword: '', newPassword: '', confirmNewPassword: '' });
    const [errors, setErrors] = React.useState({});
    const [status, setStatus] = React.useState(null);
    const [isSubmitting, setIsSubmitting] = React.useState(false);
    const loggedInEmail = React.useMemo(() => readLoggedInEmail(), []);

    const handleChange = (event) => {
      const { name, value } = event.target;
      setFormValues((current) => {
        const nextValues = Object.assign({}, current);
        nextValues[name] = value;
        return nextValues;
      });

      if (errors[name]) {
        setErrors((current) => {
          const nextErrors = Object.assign({}, current);
          nextErrors[name] = undefined;
          return nextErrors;
        });
      }

      if (status) {
        setStatus(null);
      }
    };

    const completePasswordChange = () => {
      clearSessionStorage();
      try {
        window.sessionStorage.setItem(
          PASSWORD_CHANGED_MESSAGE_KEY,
          'Your password has been changed. Please login again.'
        );
      } catch (storageError) {
        // Ignore storage failures and continue redirecting.
      }

      if (typeof navigate === 'function') {
        navigate('/auth/login');
        return;
      }

      window.location.assign('/auth/login');
    };

    const handleSubmit = async (event) => {
      event.preventDefault();
      setStatus(null);

      const disableClientValidation = Boolean(window.disableClientValidation);
      const nextErrors = disableClientValidation ? {} : validateChangePasswordFields(formValues);
      setErrors(nextErrors);
      if (!disableClientValidation && Object.keys(nextErrors).length > 0) {
        return;
      }

      const email = loggedInEmail;
      if (!email) {
        setStatus({ type: 'error', message: getValidationMessage('A Technical Error occurred.', LOGIN_TECHNICAL_ERROR_CODE) });
        return;
      }

      setIsSubmitting(true);
      try {
        const hashParamsResponse = await fetch('/api/auth/hashparams', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ email })
        });

        if (!hashParamsResponse.ok) {
          const payload = await hashParamsResponse.json().catch(() => ({}));
          setStatus({
            type: 'error',
            message: getValidationMessage('A Technical Error occurred.', payload.code != null ? payload.code : LOGIN_TECHNICAL_ERROR_CODE)
          });
          return;
        }

        const hashParamsPayload = await hashParamsResponse.json();
        const currentPasswordHash = await hashPasswordWithServerParameters(formValues.currentPassword, hashParamsPayload.passwordHashParams);
        const newPasswordHash = await hashPasswordWithArgon2(formValues.newPassword);

        const token = readAuthToken();
        const response = await fetch('/api/auth/change-password', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${token}`
          },
          body: JSON.stringify({ currentPasswordHash, newPasswordHash })
        });

        if (response.status === 401) {
          const payload = await response.json().catch(() => ({}));
          setStatus({
            type: 'error',
            message: getValidationMessage(INVALID_CREDENTIALS_MESSAGE + '.', payload.code != null ? payload.code : VALIDATION_CODES.passwordHash)
          });
          return;
        }

        if (response.status === 422) {
          const payload = await response.json().catch(() => ({}));
          setStatus({
            type: 'error',
            message: getValidationMessage('A Validation Issue occurred.', payload.code != null ? payload.code : VALIDATION_CODES.passwordHash)
          });
          return;
        }

        if (!response.ok) {
          const payload = await response.json().catch(() => ({}));
          setStatus({
            type: 'error',
            message: getValidationMessage('A Technical Error occurred.', payload.code != null ? payload.code : LOGIN_TECHNICAL_ERROR_CODE)
          });
          return;
        }

        completePasswordChange();
      } catch (error) {
        setStatus({ type: 'error', message: getValidationMessage('A Technical Error occurred.', LOGIN_TECHNICAL_ERROR_CODE) });
      } finally {
        setIsSubmitting(false);
      }
    };

    return (
      <section className="panel-card">
        {typeof BlockingScreenLoader === 'function' ? (
          <BlockingScreenLoader
            isActive={isSubmitting}
            title="Password Change in Progress"
            message="Please wait."
          />
        ) : null}

        <h3 style={{ marginTop: 0 }}>Change Password</h3>
        <p className="muted">Update the password used to sign in to your account.</p>

        <form className="form-grid" onSubmit={handleSubmit}>
          <div className="field">
            <label htmlFor="accountEmail">Email</label>
            <input
              id="accountEmail"
              name="email"
              type="email"
              value={loggedInEmail}
              readOnly
              autoComplete="username"
            />
          </div>

          <div className={`field ${errors.currentPassword ? 'invalid' : ''}`}>
            <label htmlFor="currentPassword">Current password</label>
            <input
              id="currentPassword"
              name="currentPassword"
              type="password"
              value={formValues.currentPassword}
              onChange={handleChange}
              placeholder="Enter your current password"
              autoComplete="current-password"
            />
            {errors.currentPassword && <span className="error-message">{errors.currentPassword}</span>}
          </div>

          <div className={`field ${errors.newPassword ? 'invalid' : ''}`}>
            <label htmlFor="newPassword">New password</label>
            <input
              id="newPassword"
              name="newPassword"
              type="password"
              value={formValues.newPassword}
              onChange={handleChange}
              placeholder="Choose a new password"
              autoComplete="new-password"
            />
            {errors.newPassword && <span className="error-message">{errors.newPassword}</span>}
          </div>

          <div className={`field ${errors.confirmNewPassword ? 'invalid' : ''}`}>
            <label htmlFor="confirmNewPassword">Confirm new password</label>
            <input
              id="confirmNewPassword"
              name="confirmNewPassword"
              type="password"
              value={formValues.confirmNewPassword}
              onChange={handleChange}
              placeholder="Repeat new password"
              autoComplete="new-password"
            />
            {errors.confirmNewPassword && <span className="error-message">{errors.confirmNewPassword}</span>}
          </div>

          {status && (
            <div className={`status-message ${status.type}`} role="status">
              <span>{status.message}</span>
            </div>
          )}

          <div className="hero-actions upload-hero-actions">
            <button className="primary-btn" type="submit" disabled={isSubmitting}>{isSubmitting ? 'Working...' : 'Change Password'}</button>
          </div>
        </form>
      </section>
    );
  }

  function AccountSettingsModulePage({ navigate }) {
    return (
      <div className="content auth-shell" style={{ marginTop: '0.5rem' }}>
        <section className="hero-card">
          <div>
            <h1 className="hero-title" style={{ fontSize: 'clamp(1.8rem, 2.4vw, 2.4rem)' }}>Account Settings</h1>
          </div>
        </section>

        <ChangePasswordPanel navigate={navigate} />
      </div>
    );
  }

  function readPasswordChangedMessage() {
    try {
      const message = window.sessionStorage.getItem(PASSWORD_CHANGED_MESSAGE_KEY);
      if (message) {
        window.sessionStorage.removeItem(PASSWORD_CHANGED_MESSAGE_KEY);
      }
      return message || '';
    } catch (error) {
      return '';
    }
  }

  global.PortfolioAccountSettings = {
    AccountSettingsModulePage,
    readPasswordChangedMessage,
    PASSWORD_CHANGED_MESSAGE_KEY
  };
})(window);
