<?php
/**
 * Functions for customizing the WordPress login screen.
 *
 * This file is included by the AUX parent theme functions.php.
 *
 * @todo Move this file to the TAMU plugin when that is built
 * @since 1.0.0
 */

// Exit if accessed directly
if (!defined("ABSPATH")) {
  exit();
}

/**
 * Determine if an authentication plugin is installed and activated.
 * Checks for the Authorizer plugin.
 * @todo - check for MiniOrange and other auth plugins used around A&M.
 * @since 1.0.2
 * @return bool True if an authentication plugin is installed and activated, false otherwise.
 */
function aux_is_auth_plugin_active(): bool
{
  // We need is_plugin_active to determine if an authentication plugin is installed and activated.
  // Including plugin.php because the is_plugin_active function isn't normally available on the login screen.
  include_once(ABSPATH.'wp-admin/includes/plugin.php');
  $is_auth_plugin_active = false;

  // Determine if the Authorizer plugin is installed and activated.
  // Found out the hard way that is_plugin_active() only checks if the plugin is active.
  // There are cases where a plugin can be active in the database even after the plugin folder is deleted or renamed.
  if (file_exists(ABSPATH . 'wp-content/plugins/authorizer/authorizer.php') && is_plugin_active('authorizer/authorizer.php')) {
    $is_auth_plugin_active = true;
  }

  return $is_auth_plugin_active;
}

/**
 * Obscure login screen error messages. Required by TAMUS security control IA-6: Authenticator Feedback.
 *
 * @since 1.0.0
 * @return string Login error message
 */
function aux_login_obscure(): string { return 'Sorry, your login failed!'; }
add_filter('login_errors', 'aux_login_obscure');

/**
 * Disable password reset
 * This is often abused by bots to try to gain access to a site.
 *
 * @since 1.0.0
 * @return  bool false = disable password reset
 */
function aux_disable_reset_lost_password(): bool
{
  return false;
}
add_filter('allow_password_reset', 'aux_disable_reset_lost_password');

/**
 * Custom login message if the Authorizer plugin is enabled for NetIDs
 *
 * @since 1.0.0
 * @return  string  Login message
 */
function aux_login_message(): string
{
  $login_message = '';

  if (aux_is_auth_plugin_active() === true) {
    $login_message = '<p class="message">Log in using your TAMU NetID.</p>';
  }

  return $login_message;
}
add_filter('login_message', 'aux_login_message');

/**
 * Echo link for local login to bypass NetID login
 *
 * @since 1.0.0
 */
function aux_add_show_login_link(): void
{
  $output = <<<HTML
    <div id="aux-login-link-wrapper">
      <a id="auxToggleLogin" href="#loginform">Web team &mdash; local site login</a>
    </div>
  HTML;

  echo $output;
}

// Only call this function if an authentication plugin for NetID logins is active
if (aux_is_auth_plugin_active() === true) {
  add_action('login_footer', 'aux_add_show_login_link');
}

/**
 * Change the url for the logo above the login form to the site address instead of wordpress.org.
 *
 * @since 1.0.0
 * @return  string  Address for the site
 */
function aux_login_logo_url(): string
{
  return get_bloginfo('url');
}
add_filter('login_headerurl', 'aux_login_logo_url');

/**
 * Change the link text of the header logo above the login form.
 *
 * @since 1.0.0
 * @return  string  New link text
 */
function aux_login_logo_url_title(): string
{
  return 'Texas A&amp;M University';
}
add_filter('login_headertext', 'aux_login_logo_url_title');

/**
 * Enqueue Open Sans font.
 *
 * @since 1.0.0
 */
function aux_google_fonts(): void
{
  wp_enqueue_style(
    'google-fonts',
    'https://fonts.googleapis.com/css2?family=Open+Sans:wght@300..800&display=swap'
  );
}
add_action('login_enqueue_scripts', 'aux_google_fonts');

/**
 * Echo CSS for changing the logo and other visual elements on the login page.
 * CSS to match AUX typography, card, button and alert.
 *
 * @since 1.0.0
 */
function aux_login_logo(): void
{
  $login_form_display = '';
  $default_logo = get_theme_file_uri('images/tamu-logos/TAM-stacked-maroon.svg');
  $background_image = "url($default_logo)";

  // Hide username and password field on load if the Authorizer plugin for NetID logins is active
  if (aux_is_auth_plugin_active() === true) {
    $login_form_display = <<<CSS
      #auth-external-service-login h3,
      #loginform label[for="user_login"],
      input#user_login,
      .user-pass-wrap,
      #wp-submit {
        display: none;
      }
    CSS;
  }

  // Increased specificity is intentional to override built-in WP styles
  $output = <<<HTML
    <style>
      body.login {
        background-color: #fff;
        color: #000;
        font-size: 16px;
        line-height: 1.5;
        display: flex;
        flex-direction: column;
        font-family: "Open Sans", Arial, sans-serif;

        a {
          color: #500000;
          font-weight: bold;
          text-decoration: underline;
          text-decoration-thickness: 2px;

          &:focus {
            outline: 2px dotted #af8846;
            outline-offset: .25rem;
            border: none;
            box-shadow: none;
          }
        }
      }

      .login #login {
        align-content: center;
        flex: 1 0 auto;
        width: 427px;
        padding: 0 0 20px 0;

        @media (max-height: 675px) {
          padding: 0;
        }

        label {
          font-size: 1rem;
        }

        h1 a {
          background-image: $background_image;
          background-size: contain;
          padding-bottom: 0;
          padding-left: 8px; /* Optically center - offset for the (R) on the logo */
          height: 60vh;
          width: 60vh;
          min-height: 150px;
          min-width: 150px;
          max-height: 350px;
          max-width: 350px;
          margin: 0 auto;
        }

        .message {
          text-align: center;
          border: 0 none;
          box-shadow: unset;
          display: none;
        }

        .notice {
          border-left: solid #d1d1d1 1rem;
          margin-top: 10px;
          padding: 1.375rem 1.75rem;
          display: flex;
          gap: 0.5rem;
          align-items: flex-start;

          &.notice-error {
            background: rgba(208, 67, 67, 0.12);
            border-color: #d04343;
          }

          &.notice-info {
            background: rgba(56, 159, 90, 0.12);
            border-color: #389f5a;
          }
        }

        #nav, #backtoblog, .forgetmenot {
          display: none;
        }
      }

      #loginform {
        margin: 20px auto 0 auto;
        padding: 26px 25px 20px 25px;
        width: 375px;
        border-radius: 0;
        box-shadow: rgba(0, 0, 0, 0.10) 0 1px 3px 0;
        border: 1px solid hsla(203, 50%, 30%, 0.15);

        @media (max-height: 675px) {
          margin: 0;
        }

        label {
          font-family: "Work Sans", Arial, sans-serif;
          font-size: 1rem;
          font-weight: 700;
        }

        input {
          font-size: 1rem;
        }

        input[type="text"],
        input[type="password"] {
          border-radius: 0;
          margin: .25rem 0 2rem 0;
          padding: 1rem;
          font-family: "Work Sans", Arial, sans-serif;
          border: solid #a7a7a7 2px;
          outline: solid transparent 1px;
          transition: .2s ease;

          &:focus, &:focus-visible {
            border-color: #500000;
            outline: #732f2f .3rem solid;
            box-shadow: none;
          }
        }

        .button.wp-hide-pw {
          color: #500000;

          &:focus, &:focus-visible {
            color: #500000;
            box-shadow: none;
            border: none;
            border-radius: 0;
            outline: #732f2f .3rem solid;
          }
        }
      }

      #aux-legal {
        flex-shrink: 0;
        display: block;
        max-width: 775px;
        margin: 40px auto 40px auto;
        padding: 0 10px 0 20px;

        p {
          line-height: 1.5;
          margin-bottom: 1rem;
          text-wrap: balance;
        }
      }

      #auth-external-service-login .button-external {
        margin-bottom: 15px;
      }

      #aux-login-link-wrapper {
        text-align: center;
        font-size: 1rem;
        display: block;
      }

      #wp-submit,
      .wp-core-ui .button-primary,
      #loginform #auth-external-service-login .button-external {
        background: #732f2f;
        color: #fff;
        border: none;
        position: relative;
        transition: all 0.2s ease;
        box-shadow: none;
        font-size: 1rem;
        border-radius: 8px;
        margin-top: 5px;
        padding: .3rem 1rem .2rem 1rem;

        font-family: "Work Sans", Arial, sans-serif;
        text-decoration: none;
        text-transform: uppercase;
        font-weight: 700;
        text-align: center;

        &:hover, &:focus, &:active {
          background: #500000;
          text-decoration: underline;

          .dashicons {
            text-decoration: none;
          }
        }
        &:focus {
          outline: 2px dotted #af8846;
          outline-offset: .25rem;
        }

        .label:hover {
          outline: none;
          border: none;
          background-color: transparent;
        }
      }
      #loginform #auth-external-service-login .button-external {
        margin: 5px 0 10px 0;
        padding: .5rem 1rem .2rem 1rem;
      }

      {$login_form_display}
    </style>
  HTML;

  echo $output;
}
add_action('login_enqueue_scripts', 'aux_login_logo');

/**
 * - Output the legal notice required by TAMU and TAMUS security control AC-8 System Use Notification.
 * - Toggle the display of the username and password fields and the submit button when the link is clicked.
 * - Remember the user's choice to show the NetID login button or the regular WP login form.
 *
 * @since 1.0.0
 */
function aux_login_footer_legal(): void
{
  // Convert PHP boolean to JavaScript boolean
  $js_is_auth_plugin_active = aux_is_auth_plugin_active() === true ? 'true' : 'false';

  $output = <<<HTML
    <div id="aux-legal">
      <p>This computer system and the data herein are available only for authorized
      purposes by authorized users. Use for any other purpose is prohibited and
      may result in disciplinary actions or criminal prosecution against the user.
      Usage may be subject to security testing and monitoring. There is no expectation
      of privacy on this system except as otherwise provided by applicable privacy laws.</p>
      <p>Refer to
      <a href="https://rules-saps.tamu.edu/PDFs/29.01.03.M0.02.pdf">University
        <abbr title="Standard Administrative Procedure">SAP</abbr> 29.01.03.M0.02,
        Acceptable Use</a> for more information.</p>
    </div>
    <script>
      const cookieName = 'aux_login_form_display';
      const cookieDays = 30;
      const isAuthPluginActive = $js_is_auth_plugin_active;

      // These functions need access to variables declared in the load event listener
      let toggleLoginLink, loginLabel, loginUserNameField, loginPassField, loginSubmitWrapper, loginSubmitButton, loginCasButton, loginAzureButton;

      // Set a cookie to remember the user's choice to show the NetID login button or the regular WP login form
      function setCookie(name, value, days) {
        const date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        const expires = "expires=" + date.toUTCString();
        document.cookie = name + "=" + value + ";" + expires + ";path=/";
      }

      // Get the value of a cookie
      function getCookie(name) {
        const nameEQ = name + "=";
        const cookieArray = document.cookie.split(';');
        for(let i = 0; i < cookieArray.length; i++) {
          let c = cookieArray[i];
          while (c.charAt(0) === ' ') c = c.substring(1, c.length);
          if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
      }

      // Delete the cookie
      function deleteCookie(name) {
        document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
      }

      function showLocalLogin() {
        // Show username/password fields and submit button
        if (loginLabel) loginLabel.style.display = 'block';
        if (loginUserNameField) loginUserNameField.style.display = 'block';
        if (loginPassField) loginPassField.style.display = 'block';
        if (loginSubmitWrapper) loginSubmitWrapper.style.display = 'block';
        if (loginSubmitButton) loginSubmitButton.style.display = 'block';

        // Hide NetID buttons
        if (loginCasButton) loginCasButton.style.display = 'none';
        if (loginAzureButton) loginAzureButton.style.display = 'none';

        // Update link text
        if (toggleLoginLink) {
          toggleLoginLink.innerHTML = 'Display the NetID login button';
        }

        // Remove disabled attribute from password field if it exists
        const userPassField = document.getElementById("user_pass");
        if (userPassField) {
          userPassField.removeAttribute("disabled");
        }
      }

      function showNetIDLogin() {
        // Hide username/password fields and submit button
        if (loginLabel) loginLabel.style.display = 'none';
        if (loginUserNameField) loginUserNameField.style.display = 'none';
        if (loginPassField) loginPassField.style.display = 'none';
        if (loginSubmitWrapper) loginSubmitWrapper.style.display = 'none';
        if (loginSubmitButton) loginSubmitButton.style.display = 'none';

        // Show NetID buttons
        if (loginCasButton) loginCasButton.style.display = 'block';
        if (loginAzureButton) loginAzureButton.style.display = 'block';

        // Update link text
        if (toggleLoginLink) {
          toggleLoginLink.innerHTML = 'Web team &mdash; local site login';
        }
      }

      // Wait until the document is fully loaded before executing
      window.addEventListener('load', function() {
        // Get the login link and the elements we want to toggle
        toggleLoginLink      = document.getElementById('auxToggleLogin');
        loginLabel         = document.querySelector('[for="user_login"]');
        loginUserNameField = document.querySelector('input#user_login');
        loginPassField     = document.querySelector('.user-pass-wrap');
        loginSubmitWrapper = document.querySelector('.submit');
        loginSubmitButton  = document.querySelector('#wp-submit');
        loginCasButton     = document.querySelector('#auth-external-service-login .button-cas');
        loginAzureButton   = document.querySelector('#auth-external-service-login .button-azure');

        // Check cookie on page load and restore user preference
        const savedPreference = getCookie(cookieName);

        // Show the NetID login if the Authorizer plugin is active and that's what the user chose last time
        if (savedPreference === 'netid' && isAuthPluginActive) {
          showNetIDLogin();
        } else {
          // Default to local login
          showLocalLogin();
        }

        // If auth plugin is active but there's no cookie set, show the NetID login button
        if (isAuthPluginActive && getCookie(cookieName) === null) {
          showNetIDLogin();
        }

        // If an auth plugin is active and the login link exists, add logic to toggle between local login and NetID login
        if (isAuthPluginActive && toggleLoginLink !== null) {
          // When the link is clicked, toggle between local login and NetID login
          // Set the cookie to remember the user's choice
          toggleLoginLink.addEventListener('click', function(event) {
            event.preventDefault();

            // Check current state by looking at the link text
            const isCurrentlyLocal = toggleLoginLink.innerHTML === 'Display the NetID login button' ||
                                     toggleLoginLink.innerHTML.includes('Display the NetID login button');

            if (isCurrentlyLocal) {
              // Currently showing local login, switch to NetID
              showNetIDLogin();
              setCookie(cookieName, 'netid', cookieDays);
            } else {
              // Currently showing NetID, switch to local login
              showLocalLogin();
              setCookie(cookieName, 'local', cookieDays);
            }
          }, false);
        }

      })
    </script>
  HTML;

  echo $output;
}
add_action('login_footer', 'aux_login_footer_legal');
