<?php

namespace App\Helpers;

use Illuminate\Http\Request;

trait ClientHelper
{
    /** create username */
    static function generateUsername(): string
    {
        $prefix = 'user';
        return $prefix . mt_rand(1000000, 9999999);
    }

    /** get device meta */
    static function getDeviceMeta(Request $request): array
    {
        $deviceMeta = [
            'browser' => static::getBrowser()['name'] . " " . static::getBrowser()['version'],
            'platform' => static::getOS(),
            'location' => null
        ];

        return $deviceMeta;
    }

    /** convert fa to en */
    static function faNumbersToEn($string)
    {
        // اعداد فارسی
        $persian_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
        // اعداد عربی (گاهی در متن وجود دارد)
        $arabic_numbers  = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
        // اعداد انگلیسی
        $english_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

        // ابتدا فارسی به انگلیسی
        $string = str_replace($persian_numbers, $english_numbers, $string);
        // سپس عربی به انگلیسی
        $string = str_replace($arabic_numbers, $english_numbers, $string);

        return $string;
    }

    /** get user operation system */
    static function getOS()
    {
        $user_agent = $_SERVER['HTTP_USER_AGENT'];
        $os_platform  = "Unknown";

        $os_array     = array(
            '/win32/i'              =>  'Windows',
            '/windows/i'            =>  'Windows',
            '/windows nt 10/i'      =>  'Windows',
            '/windows nt 6.3/i'     =>  'Windows',
            '/windows nt 6.2/i'     =>  'Windows',
            '/windows nt 6.1/i'     =>  'Windows',
            '/windows nt 6.0/i'     =>  'Windows',
            '/windows nt 5.2/i'     =>  'Windows',
            '/windows nt 5.1/i'     =>  'Windows',
            '/windows xp/i'         =>  'Windows',
            '/windows nt 5.0/i'     =>  'Windows',
            '/win98/i'              =>  'Windows',
            '/win95/i'              =>  'Windows',
            '/macintosh|mac os x/i' =>  'Mac',
            '/mac_powerpc/i'        =>  'Mac',
            '/linux/i'              =>  'Linux',
            '/ubuntu/i'             =>  'Linux',
            '/iphone/i'             =>  'iPhone',
            '/ipod/i'               =>  'iPod',
            '/ipad/i'               =>  'iPad',
            '/android/i'            =>  'Android',
            '/blackberry/i'         =>  'Mobile',
            '/webos/i'              =>  'Mobile'
        );

        foreach ($os_array as $regex => $value)
            if (preg_match($regex, $user_agent))
                $os_platform = $value;

        return $os_platform;
    }

    /** get browser information */
    static function getBrowser(): array
    {
        $u_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        $bname = 'Unknown';
        $platform = 'Unknown';
        $version = "?";

        // Get platform
        if (preg_match('/linux/i', $u_agent)) {
            $platform = 'Android';
        } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
            $platform = 'mac';
        } elseif (preg_match('/windows|win32/i', $u_agent)) {
            $platform = 'windows';
        }

        // Get browser name
        $ub = '';
        if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) {
            $bname = 'Internet Explorer';
            $ub = "MSIE";
        } elseif (preg_match('/Firefox/i', $u_agent)) {
            $bname = 'Mozilla Firefox';
            $ub = "Firefox";
        } elseif (preg_match('/OPR/i', $u_agent)) {
            $bname = 'Opera';
            $ub = "Opera";
        } elseif (preg_match('/Chrome/i', $u_agent) && !preg_match('/Edge/i', $u_agent)) {
            $bname = 'Google Chrome';
            $ub = "Chrome";
        } elseif (preg_match('/Safari/i', $u_agent) && !preg_match('/Edge/i', $u_agent)) {
            $bname = 'Apple Safari';
            $ub = "Safari";
        } elseif (preg_match('/Netscape/i', $u_agent)) {
            $bname = 'Netscape';
            $ub = "Netscape";
        } elseif (preg_match('/Edge/i', $u_agent)) {
            $bname = 'Edge';
            $ub = "Edge";
        } elseif (preg_match('/Trident/i', $u_agent)) {
            $bname = 'Internet Explorer';
            $ub = "MSIE";
        }

        // Get version
        $known = array('Version', $ub, 'other');
        $pattern = '#(?<browser>' . join('|', $known) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';

        if (preg_match_all($pattern, $u_agent, $matches)) {
            $i = count($matches['browser']);
            if ($i > 1) {
                $version = strripos($u_agent, "Version") < strripos($u_agent, $ub)
                    ? ($matches['version'][0] ?? '?')
                    : ($matches['version'][1] ?? '?');
            } elseif ($i === 1) {
                $version = $matches['version'][0] ?? '?';
            }
        }

        return [
            'userAgent' => $u_agent,
            'name'      => $bname,
            'version'   => $version,
            'platform'  => $platform,
            'pattern'   => $pattern,
        ];
    }


    /**
     * get user ip
     */
    function getUserIp()
    {
        $ipAddress = '';
        if (isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) {
            $ipAddress = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ipAddressList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            foreach ($ipAddressList as $ip) {
                $ip = trim($ip);
                if (filter_var($ip, FILTER_VALIDATE_IP)) {
                    $ipAddress = $ip;
                    break;
                }
            }
        } elseif (isset($_SERVER['HTTP_X_FORWARDED']) && filter_var($_SERVER['HTTP_X_FORWARDED'], FILTER_VALIDATE_IP)) {
            $ipAddress = $_SERVER['HTTP_X_FORWARDED'];
        } elseif (isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && filter_var($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'], FILTER_VALIDATE_IP)) {
            $ipAddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR']) && filter_var($_SERVER['HTTP_FORWARDED_FOR'], FILTER_VALIDATE_IP)) {
            $ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_FORWARDED']) && filter_var($_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP)) {
            $ipAddress = $_SERVER['HTTP_FORWARDED'];
        } elseif (isset($_SERVER['REMOTE_ADDR']) && filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) {
            $ipAddress = $_SERVER['REMOTE_ADDR'];
        } else {
            $ipAddress = 'UNKNOWN';
        }
        return $ipAddress;
    }

    /**
     * check for bots
     */
    protected function isBot($userAgent): bool
    {
        if (!$userAgent) {
            return false;
        }

        $bots = [
            'Googlebot',
            'Bingbot',
            'Slurp',
            'DuckDuckBot',
            'Baiduspider',
            'YandexBot',
            'Sogou',
            'Exabot',
            'facebot',
            'ia_archiver',
            'MJ12bot',
            'AhrefsBot',
            'SemrushBot',
            'DotBot',
            'PetalBot'
        ];

        foreach ($bots as $bot) {
            if (stripos($userAgent, $bot) !== false) {
                return true;
            }
        }

        return false;
    }
}
