<?php
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Handle request for custom login and block default wp-login.php and wp-signup.php
 */

/**
 * Get the URL to redirect to on failure or unauthorized access
 *
 * Retrieves the URL of the page configured for redirection when login fails
 * or unauthorized access attempts happen. If no page is selected, it defaults to the 404 page.
 *
 * @param int|null $blog_id Optional. Blog ID for multisite support.
 * @return string The valid redirect URL.
 */
function admilogu_get_fail_redirect_url($blog_id = null)
{
    if ($blog_id && is_multisite()) {
        $page_id = get_blog_option($blog_id, 'admilogu_fail_redirect_page', 0);
        if ($page_id) {
            $url = get_permalink($page_id);
            if ($url) {
                return $url;
            }
        }
        return get_home_url($blog_id, '/404');
    }

    $page_id = get_option('admilogu_fail_redirect_page', 0);
    if ($page_id) {
        $url = get_permalink($page_id);
        if ($url) {
            return $url;
        }
    }
    return home_url('/404');
}

/**
 * Handle request for custom login and block default wp-login.php
 *
 * This is the core logical function for the plugin's rewriting. It:
 * 1. Checks if the incoming request matches the custom login slug.
 * 2. If it matches, it serves the wp-login.php file internally.
 * 3. If it doesn't match, it blocks direct access to wp-login.php and wp-signup.php.
 * 4. It also blocks standard shortcuts like /admin, /dashboard for non-logged-in users.
 */
function admilogu_handle_requests()
{
    // Skip custom login URL logic if the feature is disabled
    if (!get_option('admilogu_enable_custom_login', 1)) {
        return;
    }

    // Prevent accidental triggers during AJAX or Cron
    if ((defined('DOING_AJAX') && DOING_AJAX) || (defined('DOING_CRON') && DOING_CRON)) {
        return;
    }

    $slug = trim(get_option('admilogu_login_slug', 'admin-login-guard-branding'), '/');
    if (empty($slug)) {
        return;
    }

    $request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : '';
    // Remove query string for path matching
    $request_path = untrailingslashit((string) wp_parse_url($request_uri, PHP_URL_PATH));

    // Get current site's custom login path
    $custom_login_url = home_url($slug);
    $custom_login_path = untrailingslashit((string) wp_parse_url($custom_login_url, PHP_URL_PATH));

    // If accessing custom slug, serve wp-login.php
    if (!empty($slug) && $request_path === $custom_login_path) {
        // Redirect already logged-in users to the dashboard (except when logging out)
        if (is_user_logged_in()) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $action = isset($_REQUEST['action']) ? sanitize_text_field(wp_unslash($_REQUEST['action'])) : 'login';
            if ($action !== 'logout') {
                wp_safe_redirect(admin_url());
                exit;
            }
        }

        if (!defined('admilogu_SERVING_LOGIN')) {
            define('admilogu_SERVING_LOGIN', true);
        }

        // Ensure some globals are available that wp-login.php might expect
        global $error, $user_login, $action;
        if (!isset($user_login))
            $user_login = '';
        if (!isset($error))
            $error = '';
        if (!isset($action))
            $action = 'login';

        // Prevent caching of the login page
        if (!defined('DONOTCACHEPAGE')) {
            define('DONOTCACHEPAGE', true); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound
        }

        require_once ABSPATH . 'wp-login.php';
        exit;
    }

    // Block wp-login.php or login.php directly
    if (!defined('admilogu_SERVING_LOGIN') && !is_admin()) {
        if (preg_match('/\/wp-login\.php$/i', $request_path) || preg_match('/\/login\.php$/i', $request_path)) {
            wp_safe_redirect(admilogu_get_fail_redirect_url());
            exit;
        }

        // Block wp-signup.php and wp-register.php directly
        if (preg_match('/\/wp-signup\.php$/i', $request_path) || preg_match('/\/wp-register\.php$/i', $request_path)) {
            wp_safe_redirect(admilogu_get_fail_redirect_url());
            exit;
        }
    }

    // Block /login, /admin, /dashboard standard shortcuts for logged-out users
    if (!is_user_logged_in() && get_option('admilogu_block_shortcuts', 1)) {
        $blocked_paths = ['login', 'admin', 'dashboard'];

        $home_path = untrailingslashit((string) wp_parse_url(home_url(), PHP_URL_PATH));
        $path_relative = $request_path;
        if (!empty($home_path) && strpos($request_path, $home_path) === 0) {
            $path_relative = substr($request_path, strlen($home_path));
        }
        $path_relative = trim($path_relative, '/');

        if (in_array($path_relative, $blocked_paths)) {
            wp_safe_redirect(admilogu_get_fail_redirect_url());
            exit;
        }
    }

    // Block wp-admin access for non-logged-in users (obscurity)
    if (is_admin() && !is_user_logged_in() && !defined('DOING_AJAX')) {
        if (strpos($request_uri, 'admin-ajax.php') !== false || strpos($request_uri, 'admin-post.php') !== false) {
            return;
        }
        wp_safe_redirect(admilogu_get_fail_redirect_url());
        exit;
    }
}
add_action('init', 'admilogu_handle_requests', 1);

/**
 * Filter login_url to point to custom slug
 *
 * Intercepts the `login_url` filter to replace the standard WordPress login URL
 * with the custom slug configured in the settings. It ensures redirects and
 * query parameters are preserved.
 *
 * @param string $login_url The original login URL.
 * @param string $redirect The URL to redirect to after login.
 * @param int|null $blog_id Blog ID for multisite.
 * @return string The modified login URL.
 */
function admilogu_filter_login_url($login_url, $redirect, $blog_id = null)
{
    if ($blog_id && is_multisite()) {
        $slug = get_blog_option($blog_id, 'admilogu_login_slug', 'admin-login-guard-branding');
        $url = get_home_url($blog_id, trim($slug, '/'));
    } else {
        $slug = get_option('admilogu_login_slug', 'admin-login-guard-branding');
        $url = home_url(trim($slug, '/'));
    }

    // Parse query string from original URL to preserve parameters like action=logout
    $parsed_url = wp_parse_url($login_url);
    if (isset($parsed_url['query'])) {
        parse_str($parsed_url['query'], $args);

        // If redirect provided separately, remove it from args to avoid double-handling
        if (!empty($redirect)) {
            unset($args['redirect_to']);
        }

        if (!empty($args)) {
            $url = add_query_arg($args, $url);
        }
    }

    if (!empty($redirect)) {
        $url = add_query_arg('redirect_to', urlencode($redirect), $url);
    }

    return $url;
}

/**
 * Filter site_url to correct wp-login.php links
 *
 * Intercepts `site_url` calls to ensure that any internally generated links
 * to `wp-login.php` are rewritten to the custom login slug.
 *
 * @param string $url The complete URL.
 * @param string $path The path relative to the site URL.
 * @param string|null $scheme The scheme to use.
 * @param int|null $blog_id Blog ID.
 * @return string The modified URL.
 */
function admilogu_filter_site_url($url, $path, $scheme, $blog_id = null)
{
    if ($scheme === 'login' || strpos($url, 'wp-login.php') !== false) {
        return admilogu_filter_login_url($url, null, $blog_id);
    }
    return $url;
}

/**
 * Filter login form action to point to custom slug
 *
 * @param string $url The original form action URL.
 * @return string The modified form action URL.
 */
function admilogu_filter_login_form_action($url)
{
    $slug = get_option('admilogu_login_slug', 'admin-login-guard-branding');
    if ($slug) {
        $new_url = home_url(trim($slug, '/'));

        // Preserve query parameters
        $parsed_url = wp_parse_url($url);
        if (isset($parsed_url['query'])) {
            parse_str($parsed_url['query'], $args);
            if (!empty($args)) {
                $new_url = add_query_arg($args, $new_url);
            }
        }
        return $new_url;
    }
    return $url;
}

// Only register URL rewrite filters when custom login URL is enabled
if (get_option('admilogu_enable_custom_login', 1)) {
    // Disable default WP redirections for /login, /admin, /dashboard
    remove_action('template_redirect', 'wp_redirect_admin_locations', 1000);

    add_filter('login_url', 'admilogu_filter_login_url', 10, 3);
    add_filter('site_url', 'admilogu_filter_site_url', 10, 4);
    add_filter('login_form_action', 'admilogu_filter_login_form_action', 10, 1);
}
