<?php


namespace App\Servers;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Ecs\Ecs;
use AlibabaCloud\Green\Green;
use App\Models\Config;
use App\Models\ErrorRecord;
use App\Models\Region;
use Illuminate\Support\Facades\Storage;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;


/**
 * Redis数据缓存类
 */
class CommonServer
{

    /**
     * 错误信息
     * @var string
     */
    private $errorMsg = '';

    static private $server = null;


    private function __construct()
    {

    }

    /**
     * 创建对象
     * @return CommonServer
     */
    static function creatServer()
    {
        if (empty(self::$server)) self::$server = new CommonServer();
        return self::$server;
    }

    /**
     * 验证手机号码格式
     * @param $phone
     * @return bool
     */
    public function verifyPhoneNumber($phone)
    {
        if (empty($phone)) return false;
        if (!preg_match('#^[\d]{11,11}$#', $phone)) {
            return false;
        }
        return true;
    }

    /**
     * 字符串去标签过滤及空格过滤
     * @param $str_name
     * @param $default
     * @return string
     */
    function filtrationStr($str_name, $default = '')
    {
        $str = request()->input($str_name, $default);
        if (empty($str)) return $str;
        if (!is_string($str)) {
            $str = json_encode($str);
            $str = strip_tags($str);
            $str = trim($str);
            $str = json_decode($str, true);
        } else {
            $str = strip_tags($str);
            $str = trim($str);
        }
        return $str;
    }

    /**
     * 获取城市名称
     * @param string $province_id
     * @param string $city_id
     * @param string $area_id
     * @return string
     */
    function getCityName($province_id = '', $city_id = '', $area_id = '')
    {
        $ids = [$province_id, $city_id, $area_id];
        $ids = array_filter($ids);
        if (empty($ids)) return '';
        $city_name = Region::whereIn('id', $ids)->orderBy('id', 'asc')->pluck('name')->toArray();
        $city_name = implode(' ', $city_name);
        return $city_name;

    }


    /**
     * 字符串屏蔽
     * @param $str
     * @param int $start_key 开始位置
     * @param int $end_key 尾数开始位置
     * @param int $start_num 截取位数
     * @param int $end_num 倒数截取位数
     * @param int $conceal_num 最大填充数量
     * @return string
     */
    function concealStr($str, $start_key = 0, $end_key = 1, $start_num = 1, $end_num = 1, $conceal_num = 3)
    {
        $str_len = mb_strlen($str);

        $start_str = '';
        $end_str = '';
        if (($str_len - $start_num - $end_num) < $conceal_num) {
            $conceal_num = $str_len - $start_num - $end_num;
        }
        $conceal_str = $this->getRandChar($conceal_num, '*');
        if (empty($conceal_str)) $conceal_str = '*';
        if ($str_len >= $start_key) {
            $start_str = mb_substr($str, $start_key, $start_num);
        }
        if ($str_len > $end_key) {
            $end_str = mb_substr($str, $end_key * -1, $end_num);
        }
        return $start_str . $conceal_str . $end_str;
    }


    /**
     * 获取随机字符串
     * @param int $length
     * @param string $strPol
     * @return string|null
     */
    public function getRandChar($length = 6, $strPol = '')
    {
        if ($length <= 0) $length = 1;
        $str = null;
        if (empty($strPol)) $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol) - 1;
        for ($i = 0; $i < $length; $i++) {
            $str .= $strPol[rand(0, $max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }
        return $str;
    }

    /**
     * 获取数据库配置信息
     * @param $key
     * @return mixed
     */
    function getConfigValue($key)
    {
        $key=strtolower($key);
        if(in_array($key,['sys_address','sys_private','receive_address','common_address','sediment_address'])){
            $value=env(strtoupper($key));
            if($value){
                return $value;
            }
        }
        return Config::where('key', $key)->value('value');
    }

    /**
     * 创建文件夹
     * @param $dir
     * @return bool
     */
    function creatDir($dir)
    {
        if ($dir == '') return false;
        if (!file_exists(public_path($dir))) {
            mkdir(public_path($dir), 0777, true);
            chmod(public_path($dir), 0777);
        }
        return true;
    }

    /**
     * 获取本月1号至月底
     * @param $date
     * @return array
     */
    function getNextMonth($date)
    {
        $first_day = date("Y-m-01 00:00:00", strtotime($date));
        $next_day = date("Y-m-d 23:59:59", strtotime("$first_day +1 month  -1 day"));
        return [$first_day, $next_day];
    }


    /**
     * 获取多少天后的日期
     * @param $date
     * @param $num
     * @return false|string
     */
    function getManyDate($date, $num)
    {
        if(!is_numeric($num) || $num==0){
            return $date;
        }
        if($num>0){
            $next_day = date("Y-m-d", strtotime("$date +$num day"));
        }else{
            $next_day = date("Y-m-d", strtotime("$date $num day"));
        }
        return $next_day;
    }


    /**
     * 验证是否微信浏览器
     * @return bool
     */
    function isWeixin()
    {
        $http_user_agent = request()->header('user-agent');
        if (strpos($http_user_agent, 'MicroMessenger') !== false) {
            return true;
        }
        return false;
    }

    /**
     * 格式化小数位数
     * @param $num
     * @param int $digit
     * @return string
     */
    function setFloatNum($num, $digit = 4)
    {
        return sprintf("%.{$digit}f", $num);
    }

    /**
     * 获取真实IP
     * @return mixed
     */
    function getClientIp()
    {
        $http_x_forwarded_for = request()->header('x-forwarded-for');
        if (empty($http_x_forwarded_for)) {
            return request()->getClientIp();
        } else {
            $http_x_forwarded_for = explode(',', $http_x_forwarded_for);
            return $http_x_forwarded_for[0];
        }
    }


    function delDir($dir)
    {
        //先删除目录下的文件:
        $dh = opendir($dir);
        while ($file = readdir($dh)) {
            if ($file != "." && $file != "..") {
                $fullpath = $dir . "/" . $file;
                if (!is_dir($fullpath)) {
                    unlink($fullpath);
                } else {
                    $this->deldir($fullpath);
                }
            }
        }

        closedir($dh);
        //删除当前文件夹:
        if (rmdir($dir)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 图片base64
     * @param $image_file
     * @return string
     */
    function base64EncodeImage($image_file)
    {
        $image_info = getimagesize($image_file);
        $image_data = fread(fopen($image_file, 'r'), filesize($image_file));
        $base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
        return $base64_image;
    }





    /**
     * 保留2为小数
     * @param $num
     * @param int $format_num
     * @return float|int
     */
    function setFormatNum($num,$format_num=2){
//        return  $num;
        $format_num=4;
        if(!is_numeric($num)){
            return 0;
        }
        if($format_num<0){
            return  $num;
        }elseif ($format_num==0){
            return  floor($num);
        }else{
            $num= sprintf("%.{$format_num}f", $num);
//            $multiple=pow(10,$format_num);
//            $num = floor($num*$multiple)/$multiple;
        }
        $num=$num*1;
        return  $num;
    }







    /**
     * 获取文件名
     * @param $url
     * @return string
     */
    function getFileName($url)
    {
        $name = basename($url);
        return empty($name) ? '' : $name;
    }


    /**
     * 身份证号码验证
     * @param $id
     * @return bool
     */
    public static function isIdcard($id)
    {
        $id = strtoupper($id);
        $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
        $arr_split = array();
        if (!preg_match($regx, $id)) {
            return FALSE;
        }
        if (15 == strlen($id)) //检查15位
        {
            $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";

            @preg_match($regx, $id, $arr_split);
            //检查生日日期是否正确
            $dtm_birth = "19" . $arr_split[2] . '/' . $arr_split[3] . '/' . $arr_split[4];
            if (!strtotime($dtm_birth)) {
                return FALSE;
            } else {
                return TRUE;
            }
        } else      //检查18位
        {
            $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
            @preg_match($regx, $id, $arr_split);
            $dtm_birth = $arr_split[2] . '/' . $arr_split[3] . '/' . $arr_split[4];
            if (!strtotime($dtm_birth)) //检查生日日期是否正确
            {
                return FALSE;
            } else {
                //检验18位身份证的校验码是否正确。
                //校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
                $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                $sign = 0;
                for ($i = 0; $i < 17; $i++) {
                    $b = (int)$id[$i];
                    $w = $arr_int[$i];
                    $sign += $b * $w;
                }
                $n = $sign % 11;
                $val_num = $arr_ch[$n];
                if ($val_num != substr($id, 17, 1)) {
                    return FALSE;
                }
                else {
                    return TRUE;
                }
            }
        }
    }

    /**
     * 记录错误信息
     * @param $msg
     * @param array $data
     * @param int $mId
     */
    function addErrorRecord($msg,$data=[],$mId=0){
        ErrorRecord::create([
            'm_id' => $mId,
            'msg' => $msg,
            'data' => json_encode($data)
        ]);
    }


}