<?php

use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\Session;

function success($data = [], $code = Response::HTTP_OK, $msg = '操作成功')
{
    return response()->json(['code' => $code, 'data' => $data, 'msg' => $msg]);
}

function error(string $msg, $code = Response::HTTP_INTERNAL_SERVER_ERROR)
{
    return response()->json(['code' => $code, 'msg' => $msg]);
}


function handler_drive($callback)
{
    try {
        if (!is_callable($callback)) {
            throw new \Exception('callback is not callable');
        }
        $result = $callback();
    } catch (\Exception $e) {
        $error_message = $e->getMessage();
        $result = \App\Tool\ToolFunc::handlerException($e);
        if ($result) {
            $message = json_decode($error_message, true);
            $exception = '\\App\\Exceptions\\' . $result[0];
            throw new $exception(...$message);
        }

        throw new \App\Exceptions\ControllerException($error_message);
    }
    return $result;
}

/**
 * 通过curl获取数据
 * @param $url
 * @param bool $isHearder
 * @param bool $post
 * @return mixed
 */
function http_request_code($url, $isHearder = null, $post = 'GET', $data = null, $timeout = 1)
{



  //  初始化curl
    $ch = curl_init();
    //设置URL地址
    curl_setopt($ch, CURLOPT_URL, $url);

    //设置header信息
    if (!empty($isHearder)) {
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER,$isHearder);
    }
    //如果是post，则把data的数据传递过去

    if (($post == 'POST') ) {
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    //如果是删除方法，则是以delete请求或者Post请求
    if ($post == 'DELETE' || $post == 'POST') {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $post);
    }
    curl_setopt($ch, CURLOPT_TIMEOUT, 0);

    //设置超时时间，毫秒
//    curl_setopt($ch, CURLOPT_TIMEOUT_MS, $timeout * 100);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    //执行CURL时间
    $result = curl_exec($ch);


    //如果有异常，记录到日志当中
    $curl_errno = curl_errno($ch);
    if ($curl_errno > 0) {
    }


    //关闭URL，返回数据
    curl_close($ch);
    return $result;
}

/**
 * 记录本地日志
 * @param $content
 * @param bool $clean
 * @param bool $exit
 */
function nodeFileLog($content, $clean = false)
{
    //转换成json存储
    $content = json_encode($content, JSON_UNESCAPED_UNICODE) . PHP_EOL;

    //判断是否覆盖
    $append = $clean ? null : FILE_APPEND;

    //写入日志
    $date = date('Y-m-d');
    file_put_contents("/data/logs/simple{$date}.json", $content, $append);

}

#获取客户端ip
function getIp()
{

    if (isset ($_SERVER ['HTTP_X_FORWARDED_FOR'])) {
        $clientIP = $_SERVER ['HTTP_X_FORWARDED_FOR'];
    } elseif (isset ($_SERVER ['HTTP_X_REAL_IP'])) {
        $clientIP = $_SERVER ['HTTP_X_REAL_IP'];
    } else {
        $clientIP = $_SERVER['REMOTE_ADDR'];
    }

//    addLog($_SERVER);

    return $clientIP;
}

#比较两个日期字符串的大小
function compare_data($data1, $data2)
{
    return (strtotime($data1) > strtotime($data2)) ? true : false;
}


function updateRule($rule, $data)
{
    foreach ($data as $key => $val) {
        if (!isset($rule[$key])) {
            continue;
        }

        foreach ($rule[$key] as $rkey => $rval) {
            $tmp = check($val, $rval, $rkey);
            if ($tmp == false) {
                return error("未通过验证规则:$key-$rkey-" . json_encode($rval));
            }
        }
    }
}


/**
 * 验证数据 支持 in between equal length regex expire
 * @access public
 * @param string $value 验证数据
 * @param mixed $rule 验证表达式
 * @param string $type 验证方式 默认为正则验证
 * @return boolean
 */
function check($value, $rule, $type = 'regex')
{
    $type = strtolower(trim($type));
    switch ($type) {
        case 'in':// 验证是否在某个指定范围之内 逗号分隔字符串或者数组
        case 'notin':
            $range = is_array($rule) ? $rule : explode(',', $rule);
            return 'in' == $type ? in_array($value, $range) : !in_array($value, $range);
        case 'between':// 验证是否在某个范围
        case 'notbetween':    // 验证是否不在某个范围
            if (is_array($rule)) {
                $min = $rule[0];
                $max = $rule[1];
            } else {
                list($min, $max) = explode(',', $rule);
            }
            return 'between' == $type ? $value >= $min && $value <= $max : $value < $min || $value > $max;
        case 'equal':// 验证是否等于某个值
        case 'notequal':    // 验证是否等于某个值
            return 'equal' == $type ? $value == $rule : $value != $rule;
        case 'length':    // 验证长度
            $length = mb_strlen($value, 'utf-8');     // 当前数据长度
            if (strpos($rule, ',')) {
                // 长度区间
                list($min, $max) = explode(',', $rule);
                return $length >= $min && $length <= $max;
            } else {
                // 指定长度
                return $length == $rule;
            }
        case 'expire':
            list($start, $end) = explode(',', $rule);
            if (!is_numeric($start)) {
                $start = strtotime($start);
            }

            if (!is_numeric($end)) {
                $end = strtotime($end);
            }

            return NOW_TIME >= $start && NOW_TIME <= $end;
        case 'regex':
        default:    // 默认使用正则验证 可以使用验证类中定义的验证名称
            // 检查附加规则
            return regex($value, $rule);
    }
}


/**
 * 使用正则验证数据
 * @access public
 * @param string $value 要验证的数据
 * @param string $rule 验证规则
 * @return boolean
 */
function regex($value, $rule)
{
    $validate = array(
        'require' => '/\S+/',
        'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/',
        'url' => '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/',
        'currency' => '/^\d+(\.\d+)?$/',
        'number' => '/^\d+$/',
        'zip' => '/^\d{6}$/',
        'integer' => '/^[-\+]?\d+$/',
        'double' => '/^[-\+]?\d+(\.\d+)?$/',
        'english' => '/^[A-Za-z]+$/',
        'datetime' => '/^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/',
    );
    // 检查是否有内置的正则表达式
    if (isset($validate[strtolower($rule)])) {
        $rule = $validate[strtolower($rule)];
    }


    return preg_match($rule, $value) === 1;
}

/**
 * 获取用户基本信息
 * @return array|mixed
 */
function getAdmin(){
    $userStr = Session::get("user");


    if (!$userStr){

        $user = new stdClass();
        $user->name = '';

    }else{
        $user = json_decode($userStr);
    }

    return $user;
}

function parse_custom_str($str, $handle = '/')
{
    $str = substr($str, strpos($str, $handle) + 1);
    return $str;
}

function get_prefix()
{
    $current = \Illuminate\Support\Facades\URL::current();

    $url_arr = explode('/', $current);

    $prefix = '/' . $url_arr[3] ?? '/web';

    return $prefix;
}

/**
 *  生成UUID标识并检测UUID是否重复
 */
function generateRandomNum( $len = 32, $md5 = true ) {
    # Seed random number generator
    # Only needed for PHP versions prior to 4.2
    mt_srand( (double)microtime()*1000000 );
    # Array of characters, adjust as desired
    $chars = array(
        'Q', '@', '8', 'y', '%', '^', '5', 'Z', '(', 'G', '_', 'O', '`',
        'S', '-', 'N', '<', 'D', '{', '}', '[', ']', 'h', ';', 'W', '.',
        '/', '|', ':', '1', 'E', 'L', '4', '&', '6', '7', '#', '9', 'a',
        'A', 'b', 'B', '~', 'C', 'd', '>', 'e', '2', 'f', 'P', 'g', ')',
        '?', 'H', 'i', 'X', 'U', 'J', 'k', 'r', 'l', '3', 't', 'M', 'n',
        '=', 'o', '+', 'p', 'F', 'q', '!', 'K', 'R', 's', 'c', 'm', 'T',
        'v', 'j', 'u', 'V', 'w', ',', 'x', 'I', '$', 'Y', 'z', '*'
    );
    # Array indice friendly number of chars;
    $numChars = count($chars) - 1; $token = '';
    # Create random token at the specified length
    for ( $i=0; $i<$len; $i++ )
        $token .= $chars[ mt_rand(0, $numChars) ];
    # Should token be run through md5?
    if ( $md5 ) {
        # Number of 32 char chunks
        $chunks = ceil( strlen($token) / 32 ); $md5token = '';
        # Run each chunk through md5
        for ( $i=1; $i<=$chunks; $i++ )
            $md5token .= md5( substr($token, $i * 32 - 32, 32) );
        # Trim the token
        $token = substr($md5token, 0, $len);
    }
    return $token;
}

/**
 * 获取rbac统一验权
 * @return string
 */
function getRbac($request,$url='api/ram',$category_id = '' ,$type='base'){

    if ($category_id){
        $appid = $category_id;
    }else{
        $appid = $request->category_id??"";
    }

    $mis_uid = $request->mis_uid;


    //https://api.eoffcn.com/demo/get?t=xx&sign=xx&ak=xx
    //其中sign=md5(ak=$ak&t=时间戳&sk=$sk)

    $rbac = getenv('rbac')?getenv('rbac'):'http://api.t.eoffcn.com';


    $rbac_ak = getenv('rbac_ak')?getenv('rbac_ak'):'12485d7307bf347ee5834f98f5465aa4';
    $rbac_sk = getenv('rbac_sk')?getenv('rbac_sk'):'3d279dde16162fcd4e173707d129d036';
    $time = time();

    $sign = md5('ak='.$rbac_ak.'&t='.$time.'&sk='.$rbac_sk);

    switch ($type){

        case 'base':
            $rbac_url = $rbac.'/rbac/'.$url.'?t='.$time.'&sign='.$sign.'&ak='.$rbac_ak.'&appid='.$appid.'&uid='.$mis_uid;
            break;

        case 'mis_user':  //获取mis员工基本信息
            $staffNo = $request->username;
            $rbac_url = $rbac.'/rbac/'.$url.'?t='.$time.'&sign='.$sign.'&ak='.$rbac_ak.'&staffNo='.$staffNo;
            break;

        default:
            $rbac_url = $rbac.'/rbac/'.$url.'?t='.$time.'&sign='.$sign.'&ak='.$rbac_ak.'&appid='.$appid.'&uid='.$mis_uid;

    }

    //$rbac_url = $rbac.'/rbac/'.$url.'?t='.$time.'&sign='.$sign.'&ak='.$rbac_ak.'&appid='.$appid.'&uid='.$mis_uid;

    return $rbac_url;
}


function sign($username)
{
    $time = time();
    $key = getenv("MIS_SIN_KEY")?getenv("MIS_SIN_KEY"):"ca780358d798c00dc18e148c9eaf618c";
    return ['time' => $time, 'sign' => md5($username . $key . $time)];
}