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

trait Calliope_SP_Master_Utilities {
    private function safe_redirect($url) {
        $url = esc_url_raw((string) $url);

        if (!$url) {
            wp_die(esc_html__('Invalid redirect URL.', 'calliope-social-publisher'));
        }

        $host = wp_parse_url($url, PHP_URL_HOST);
        $scheme = wp_parse_url($url, PHP_URL_SCHEME);

        $current_hosts = array_filter(array_map(static function ($candidate_url) {
            return strtolower((string) wp_parse_url((string) $candidate_url, PHP_URL_HOST));
        }, [
            home_url(),
            site_url(),
            admin_url(),
        ]));
        $is_current_site_host = $host && in_array(strtolower((string) $host), $current_hosts, true);

        if ($host && $scheme && !$is_current_site_host && !in_array(strtolower((string) $scheme), ['https'], true)) {
            wp_die(esc_html__('Invalid redirect URL.', 'calliope-social-publisher'));
        }

        if ($host) {
            add_filter('allowed_redirect_hosts', static function ($hosts) use ($host) {
                $defaults = [
                    'www.facebook.com',
                    'www.tumblr.com',
                    'www.pinterest.com',
                    'threads.net',
                    'www.linkedin.com',
                    'www.instagram.com',
                    'accounts.google.com',
                ];

                $hosts[] = $host;

                return array_values(array_unique(array_merge($hosts, $defaults)));
            });
        }

        wp_safe_redirect($url);
        exit;
    }

    private function redirect_msg($type, $msg, $tab = 'dashboard', $net = '', $extra_args = []) {
        $args = [
            'page'    => 'calliope-social-publisher',
            'tab'     => $tab,
    // Preserve the active network tab after saving or testing.
            'calliope_sp_type' => $type,
        ];

        if ($tab === 'connections') {
            // Preserve the active network tab after save/test actions.
            // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Request values are used only to preserve the current UI tab after safe redirects.
            if (!$net && !empty($_REQUEST['calliope_sp_net'])) {
                $net = sanitize_key(wp_unslash($_REQUEST['calliope_sp_net']));
            }

            if (!$net && !empty($_REQUEST['action'])) {
                $act = sanitize_key(wp_unslash($_REQUEST['action']));
                foreach (['threads','pinterest','tumblr','mastodon','bluesky','instagram','linkedin','blogger','facebook'] as $candidate) {
                    if (strpos($act, $candidate) !== false) {
                        $net = $candidate;
                        break;
                    }
                }
            }

            if ($net) {
                $args['net'] = $net;
            }
            // phpcs:enable WordPress.Security.NonceVerification.Recommended
        }

        $args['calliope_sp_msg'] = (string) $msg;

        if (is_array($extra_args) && !empty($extra_args)) {
            foreach ($extra_args as $extra_key => $extra_value) {
                $args[sanitize_key((string) $extra_key)] = is_scalar($extra_value) ? (string) $extra_value : '';
            }
        }

        $this->safe_redirect(add_query_arg($args, admin_url('admin.php')));
    }

    private function normalize_instance($instance) {
        $instance = trim((string) $instance);

        if ($instance === '') {
            return '';
        }

        if (preg_match('/@[^@\s]+@([^@\s\/]+)/', $instance, $m)) {
            $instance = $m[1];
        }

        if (preg_match('#^[a-z][a-z0-9+.-]*://#i', $instance)) {
            $scheme = strtolower((string) wp_parse_url($instance, PHP_URL_SCHEME));
            if ($scheme !== 'https') {
                return '';
            }

            $host = wp_parse_url($instance, PHP_URL_HOST);
            if (!empty($host)) {
                $instance = (string) $host;
            } else {
                return '';
            }
        }

        $instance = preg_replace('#^[a-z][a-z0-9+.-]*://#i', '', $instance);
        $instance = preg_replace('#^www\.#i', '', $instance);
        $instance = trim($instance);
        $instance = preg_replace('#/.*$#', '', $instance);
        $instance = strtolower(rtrim($instance, "/ \t\n\r\0\x0B."));
        $instance = trim($instance, '[]');

        if (!$this->is_safe_public_instance_host($instance)) {
            return '';
        }

        return sanitize_text_field($instance);
    }

    private function is_safe_public_instance_host($host) {
        return Calliope_SP_Host_Validator::is_safe_public_host($host, true);
    }

    private function get_invalid_mastodon_instance_message() {
        return __('Mastodon: enter a public HTTPS server, for example mastodon.social. Localhost, private/reserved IPs and non-HTTPS URLs are not allowed.', 'calliope-social-publisher');
    }

    private function safe_basic_auth_header($user, $pass) {
        $raw = (string)$user . ':' . (string)$pass;
        return 'Basic ' . base64_encode($raw);
    }
}
