<?php

namespace Clonable\Helpers;

use Clonable\Objects\ClonableConfig;
use Clonable\Helpers\TextTranslator;

class Functions
{
    /**
     * @param string $haystack
     * @param string|array $needle
     * @return bool
     */
    public static function str_starts_with($haystack, $needle)
    {
        if (is_array($needle)) {
            foreach ($needle as $n) {
                if (self::str_starts_with($haystack, $n)) {
                    return true;
                }
            }
            return false;
        }

        if ($haystack === null || $needle === null) {
            return false;
        }

        if ($needle === '') {
            return true;
        }

        return strpos($haystack, $needle) === 0;
    }

    public static function str_ends_with($haystack, $needle)
    {
        if ($haystack === '' && $needle !== '') {
            return false;
        }
        $len = strlen($needle);

        return substr_compare($haystack, $needle, -$len, $len) === 0;
    }

    /**
     * Use to trim a specific part from the start of a string.
     * Also trim the whitespaces for the beginning and end.
     * @param $input string the input string.
     * @param $trim string the part the trim
     * @return string
     */
    public static function str_trim_start($input, $trim)
    {
        while (self::str_starts_with($input, $trim)) {
            $input = substr($input, strlen($trim));
        }
        return trim(($input ?? ''));
    }

    /**
     * Debug function for printing data in a nice format
     * Will stop the current process
     * @param $value mixed the data you want to show
     * @return void no return, this function prints
     */
    public static function dd($value)
    {
        self::dump($value);
        die();
    }

    public static function dump($value)
    {
        echo "<pre>" . esc_html(print_r($value, true)) . "</pre>";
    }

    public static function is_clonable_page()
    {
        if (isset($_GET)) {
            $get_data = wp_unslash($_GET);
            $current_page = ($get_data['page'] ?? null);
            return $current_page == 'clonable';
        }
        return false;
    }

    public static function can_log_sensitive()
    {
        if (current_user_can('administrator')) {
            return true;
        }

        $api_key = get_option('clonable_api_key');
        if ($api_key === null || $api_key === false || $api_key === "") {
            return false;
        }

        $headers = getallheaders();
        $debug_header = array_filter($headers, function ($header_value, $header_name) use ($api_key) {
            return strtolower($header_name) === 'x-clonable-debug' && $header_value === $api_key;
        }, ARRAY_FILTER_USE_BOTH);

        return count($debug_header) > 0;
    }

    /**
     * Get the scheme + domain of the website without the path.
     * get_site_url or get_home_url can return an url with a path.
     * this function makes sure this path is never included.
     *
     * @param string|null $url input url the get the domain from
     * @return string
     */
    public static function get_root_domain($url = null)
    {
        $full_url = $url ?? get_site_url();
        $url_parts = parse_url($full_url);

        // if the url parts can be parsed, create a new url
        if ($url_parts !== false) {
            return $url_parts['scheme'] . "://" . $url_parts['host'];
        }

        // if the input url is null, we can retry it with the home url
        if ($url === null) {
            return self::get_root_domain(get_home_url());
        }

        return $full_url; // use this as back-up if no url can be constructed
    }

    /**
     * Returns default countries per domain, merging saved data with current clone/site domains.
     *
     * @param array $domains Optional list of domains to filter (currently unused).
     * @return array
     */
    public static function get_default_countries_per_domain()
    {
        // Get all relevant domains (clones + site)
        $clone_urls = [];
        $site = ClonableConfig::get_site();

        if ($site) {
            foreach ($site->get_clones() as $index => $clone) {
                $url = $site->get_clone_url($index);
                $parsed = parse_url($url);
                $clone_urls[] = $parsed['host'] . ($parsed['path'] ?? '');
            }
        }

        // Add main site domain
        $site_url = get_option('siteurl');
        $parsed_site = parse_url($site_url);
        $site_domain = $parsed_site['host'] . ($parsed_site['path'] ?? '');
        if (!in_array($site_domain, $clone_urls, true)) {
            array_unshift($clone_urls, $site_domain);
        }

        $clone_urls = array_unique($clone_urls);

        // Load saved country data
        $saved_by_domain = [];
        $option = get_option('clonable_default_country_by_domain', '');
        if (is_string($option) && $option !== '' && str_contains($option, '[')) {
            $decoded = json_decode($option, true);
            if (is_array($decoded)) {
                foreach ($decoded as $row) {
                    if (!empty($row['domain'])) {
                        $saved_by_domain[$row['domain']] = [
                            'domain' => $row['domain'],
                            'billing_country' => $row['billing_country'] ?? '',
                            'shipping_country' => $row['shipping_country'] ?? '',
                            'restrict_to_default' => !empty($row['restrict_to_default']),
                        ];
                    }
                }
            }
        }

        // Build result rows for each domain
        $rows = [];
        foreach ($clone_urls as $domain) {
            $rows[] = $saved_by_domain[$domain] ?? [
                'domain' => $domain,
                'billing_country' => '',
                'shipping_country' => '',
                'restrict_to_default' => false,
            ];
        }

        return $rows;
    }

    public static function minify_html($html = '', $active = true)
    {
        if (empty($html)) {
            return $html;
        }
        // Remove comments
        $html = preg_replace('/<!--(?!<!)[^\[>].*?-->/', '', $html);
        // Remove whitespace between tags
        $html = preg_replace('/>\s+</', '><', $html);
        // Remove leading and trailing whitespace
        $html = trim($html);
        // remove multiple spaces
        $html = preg_replace('/\s+/', ' ', $html);

        // remove inline js and css comments
        $html = preg_replace_callback('/(<script\b[^>]*>)([\s\S]*?)(<\/script>)/', function ($matches) {
            $script_open = $matches[1];
            $script_content = $matches[2];
            $script_close = $matches[3];

            // Remove JS comments
            $script_content = preg_replace('/\/\/.*(?=[\n\r])|\/\*[\s\S]*?\*\//', '', $script_content);

            return $script_open . $script_content . $script_close;
        }, $html);


        return $html;
    }

	public static function lower(string $value): string {
		return function_exists('mb_strtolower') ? mb_strtolower($value) : strtolower($value);
	}

	public static function sanitize_text(string $text) {
		if (empty($text)) {
			return "";
		}
		$value = trim($text);
		if (function_exists('sanitize_text_field')) {
			return sanitize_text_field($value);
		}

		// Fallback for non-WP contexts (static analysis / early load).
		$value = strip_tags($value);
		$value = preg_replace('/[\r\n\t\0\x0B]+/u' ,' ' ,$value);

		return trim((string) $value);
	}

	public static function sanitize_email(string $email) {
		if (empty($text)) {
			return "";
		}
		$value = trim($email);
		if (function_exists('sanitize_email')) {
			return sanitize_email($value);
		}

		$sanitized = (string) filter_var($value ,FILTER_SANITIZE_EMAIL);
		return is_string($sanitized) ? $sanitized : '';
	}
}
