<?php

use Carbon\Carbon;
use Illuminate\Support\Str;

if (! function_exists('dmy')) {
    function dmy(Carbon $carbon)
    {

        return $carbon->format('d M Y');

    }
}

if (! function_exists('epoch_now_timestamp')) {
    function epoch_now_timestamp($multiplier = 1000)
    {
        return (int) round(microtime(true) * $multiplier);
    }
}

if (! function_exists('add_params_to_url')) {
    function add_params_to_url(string $url, array $newParams): string
    {
        $url = parse_url($url);
        parse_str($url['query'] ?? '', $existingParams);

        $newQuery = array_merge($existingParams, $newParams);

        $newUrl = $url['scheme'].'://'.$url['host'].($url['path'] ?? '');
        if ($newQuery) {
            $newUrl .= '?'.http_build_query($newQuery);
        }

        if (isset($url['fragment'])) {
            $newUrl .= '#'.$url['fragment'];
        }

        return $newUrl;
    }
}

if (! function_exists('markdown_to_plaintext')) {
    function markdown_to_plaintext($markdown)
    {
        // Headers
        $markdown = preg_replace('/^#.*$/m', '', $markdown);
        // Links and images
        $markdown = preg_replace('/\[(.*?)\]\(.*?\)/', '$1', $markdown);
        // Bold and italic
        $markdown = str_replace(['**', '__', '*', '_'], '', $markdown);
        // Ordered and unordered lists
        $markdown = preg_replace('/^[-\*].*$/m', '', $markdown);
        // Horizontal line
        $markdown = str_replace(['---', '***', '- - -', '* * *'], '', $markdown);
        // Inline code and code blocks
        $markdown = preg_replace('/`.*?`/', '', $markdown);
        $markdown = preg_replace('/```[\s\S]*?```/', '', $markdown);
        // Blockquotes
        $markdown = preg_replace('/^>.*$/m', '', $markdown);

        // Remove multiple spaces, leading and trailing spaces
        $plaintext = trim(preg_replace('/\s+/', ' ', $markdown));

        return $plaintext;
    }
}

if (! function_exists('round_to_nearest_base')) {
    function round_to_nearest_base($number, $postfix = '+', $base = null)
    {
        // If $base is not provided, determine the base dynamically
        if ($base === null) {
            $length = strlen((string) $number);
            if ($length > 1) {
                $base = pow(10, $length - 2);
            } else {
                $base = 1;
            }
        }

        $roundedNumber = floor($number / $base) * $base;

        return $roundedNumber.$postfix;
    }
}

if (! function_exists('remove_query_parameters')) {
    function remove_query_parameters($url)
    {
        // Trim the URL to remove whitespace, newline characters, and trailing slashes
        $trimmedUrl = rtrim(trim($url), '/');

        // Parse the trimmed URL
        $parsedUrl = parse_url($trimmedUrl);

        // Rebuild the URL without the query string
        $rebuiltUrl = $parsedUrl['scheme'].'://'.$parsedUrl['host'];
        if (isset($parsedUrl['path']) && $parsedUrl['path'] !== '/') {
            $rebuiltUrl .= $parsedUrl['path'];
        }

        return $rebuiltUrl;
    }
}

if (! function_exists('remove_referral_parameters')) {
    function remove_referral_parameters($url)
    {
        $referralParameters = [
            'aff', 'ref', 'via',
            'utm_source', 'utm_medium', 'utm_campaign',
            'utm_content', 'utm_term', 'partner',
            'click_id', 'affiliate', 'source',
            'referral', 'tracker', 'tracking_id',
            'promo', 'coupon', 'discount',
            'campaign', 'ad', 'ad_id',
            // Add more parameters as needed
        ];

        // Parse the URL
        $parsedUrl = parse_url($url);
        if (! isset($parsedUrl['query'])) {
            return $url; // No query string present, return original URL
        }

        // Parse the query string
        parse_str($parsedUrl['query'], $queryParams);

        // Remove referral parameters
        foreach ($referralParameters as $param) {
            unset($queryParams[$param]);
        }

        // Rebuild query string
        $queryString = http_build_query($queryParams);

        // Rebuild the URL
        $rebuiltUrl = $parsedUrl['scheme'].'://'.$parsedUrl['host'];
        if (isset($parsedUrl['path'])) {
            $rebuiltUrl .= $parsedUrl['path'];
        }
        if (! empty($queryString)) {
            $rebuiltUrl .= '?'.$queryString;
        }

        return $rebuiltUrl;
    }
}

if (! function_exists('get_domain_from_url')) {
    function get_domain_from_url($url)
    {
        $parse = parse_url($url);

        // Check if 'host' key exists in the parsed URL array
        if (! isset($parse['host'])) {
            return null; // or you can throw an exception or handle this case as per your requirement
        }

        $host = $parse['host'];

        // Check if the domain starts with 'www.' and remove it
        if (substr($host, 0, 4) === 'www.') {
            $host = substr($host, 4);
        }

        return $host;
    }
}

if (! function_exists('get_tld_from_url')) {
    function get_tld_from_url($url)
    {
        // Parse the URL and return its components
        $parsedUrl = parse_url($url);

        // Check if the 'host' part is set
        if (isset($parsedUrl['host'])) {
            // Split the host by dots
            $hostParts = explode('.', $parsedUrl['host']);

            // Return the last part which should be the TLD
            return end($hostParts);
        }

        // Return false if the URL doesn't have a host component
        return false;
    }
}

if (! function_exists('str_first_sentence')) {
    function str_first_sentence($str)
    {
        // Split the string at ., !, or ?
        $sentences = preg_split('/(\.|!|\?)(\s|$)/', $str, 2);

        // Return the first part of the array if available
        if (isset($sentences[0])) {
            return trim($sentences[0]).'.';
        }

        // If no sentence ending found, return the whole string
        return $str;
    }

}

if (! function_exists('str_extract_sentences')) {
    function str_extract_sentences($str, $count = 1)
    {
        // Split the string at ., !, or ?, including the punctuation in the result
        $sentences = preg_split('/([.!?])\s*/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

        $extractedSentences = [];
        $currentSentence = '';

        foreach ($sentences as $key => $sentence) {
            if ($key % 2 == 0) {
                // This is a sentence fragment
                $currentSentence = $sentence;
            } else {
                // This is a punctuation mark
                $currentSentence .= $sentence;
                $extractedSentences[] = trim($currentSentence);

                if (count($extractedSentences) >= $count) {
                    break;
                }
            }
        }

        return $extractedSentences;
    }
}

if (! function_exists('unslug')) {
    function unslug($slug, $delimiter = '-')
    {
        return ucwords(str_replace($delimiter, ' ', $slug));
    }
}

if (! function_exists('str_slug')) {
    function str_slug($string, $delimiter = '-')
    {
        return Str::of(trim($string))->slug($delimiter);
    }
}

if (! function_exists('is_empty')) {
    /**
     * A better function to check if a value is empty or null. Strings, arrays, and Objects are supported.
     *
     * @param  mixed  $value
     */
    function is_empty($value): bool
    {
        if (is_null($value)) {
            return true;
        }

        if (is_string($value)) {
            if ($value === '') {
                return true;
            }
        }

        if (is_array($value)) {
            if (count($value) === 0) {
                return true;
            }
        }

        if (is_object($value)) {
            $value = (array) $value;

            if (count($value) === 0) {
                return true;
            }
        }

        return false;
    }
}

if (! function_exists('get_country_name_by_iso')) {
    function get_country_name_by_iso($country_iso)
    {
        if (! is_empty($country_iso)) {

            $country_iso = strtoupper($country_iso);

            try {
                return config("platform.country_codes.{$country_iso}")['name'];
            } catch (\Exception $e) {
            }

        }

        return 'International';
    }
}

if (! function_exists('get_country_emoji_by_iso')) {
    function get_country_emoji_by_iso($country_iso)
    {
        if (! is_empty($country_iso)) {

            $country_iso = strtoupper($country_iso);

            try {
                return config("platform.country_codes.{$country_iso}")['emoji'];
            } catch (\Exception $e) {
            }

        }

        return '🌎';
    }
}

if (! function_exists('str_random')) {
    function str_random($length = 10)
    {
        return Str::random($length);
    }
}
