<?php

use Model\emailSql;


/**
 * 进程pid
 * @return int
 * @author:dc
 * @time 2023/2/18 14:00
 */
function posix_pid(){
    $pid = getmypid();
    return $pid ? $pid : 0;
}


/**
 * redis 驱动
 * @return \Lib\RedisPool|\Lib\Redis
 * @author:dc
 * @time 2023/2/13 9:44
 */
function redis():\Lib\RedisPool|\Lib\Redis {

    if(co::getCid() != -1){
        return new \Lib\RedisPool();
    }

    return \Lib\Redis::instance();

}


/**
 * 操作db
 * @return \Lib\Db|\Lib\DbPool
 * @author:dc
 * @time 2023/2/13 14:15
 */
function db():\Lib\Db|\Lib\DbPool{
    // 池子
    if(co::getCid() != -1){
        return new \Lib\DbPool();
    }
    // 非池子
    return \Lib\Db::instance();
}




/**
 * 记录日志
 * @param $message
 * @author:dc
 * @time 2023/2/10 14:58
 */
function logs($message,$filename=null){
    if(is_array($message)){
        $message = print_r($message,true);
    }
//    $a = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT,4);
//    $message .= print_r($a,1);
    return \Lib\Log::append($message, $filename);

}


/**
 * 消息输出
 * @param $message
 * @author:dc
 * @time 2023/2/10 15:42
 */
function _echo($message){
    $message = '['.getmypid().'] '.date('Y-m-d H:i:s').' '.$message."\n";
    if(php_sapi_name()=='cli'){
        echo $message;
    }else{
        logs($message);
    }
}



/**
 * 文本消息,多语言
 * @param $key
 * @return mixed
 * @author:dc
 * @time 2023/2/13 10:51
 */
function __($key):mixed{
    return $key ? \Lib\Lang::msg($key) : '';
}


/**
 * @return \Lib\App
 * @author:dc
 * @time 2023/2/13 11:48
 */
function app():\Lib\App{
    return \Lib\App::instance();
}


/**
 * 过滤函数
 * @param $value
 * @param null $filter
 * @return array|false|float|int|mixed
 * @author:dc
 * @time 2023/2/13 11:54
 */
function my_filter($value,$filter=null){
    if(is_array($value)){
        foreach ($value as $key=>$val){
            $value[$key]    =   my_filter($val,$filter);
        }
    } else {
        // 过滤函数
        if(!is_array($filter)){
            $filter =   [$filter];
        }
        // 合并默认过滤
        $filter =   array_merge(['trim'], $filter);

        // 循环过滤
        foreach ($filter as $fil){
            $fil && $value  =   call_user_func($fil,$value);
        }
    }
    // 强制转类型
    if(is_numeric($value)&&strlen($value)<10&&intval(substr($value,0,1))!==0){
        if(str_contains($value, '.')){
            $value = floatval($value);
        }else{
            $value = intval($value);
        }
    }

    return $value;
}

/**
 *  db 组合条件
 * @param array $where
 * [
 *  '字段'=>'value',
 *  '字段.in'=>['value',...],
 *  '字段.notin'=>['value',...],
 *  '字段.like'=>'value',
 *  '字段.not like'=>'value',
 *  '字段.not in'=>['value',...],
 *  '字段.between'=>['value',...]
 *  '_' =>  'sql' 或者使用 '_'    =>  ['sql','sql',...]
 * ]
 * @param string $ar 每个条件之间的连接符号 or/and
 * @return string
 * @author:dc
 * @time 2023/2/17 10:41
 */
function dbWhere(array $where, string $ar = 'and'):string{
    $sql = [];
    foreach ($where as $f=>$v){

        list($f,$t) = explode('.',$f.'.');
        if($f!=='_'){
            $f = '`'.str_replace('|','`.`',$f).'`';
        }

        if(is_array($v)){
            if($f ==='_'){
                $sql = array_merge($sql,$v);
                continue;
            }
            $v = array_map(function ($n){
                if (is_string($n)){
                    return "'".addslashes($n)."'";
                }
                return $n;
            },$v);
            if(count($v)===1){
                if($t=='notin'){
                    $sql[] = "{$f} != ".$v[0];
                }elseif($t){
                    $sql[] = "{$f} {$t} ".$v[0];
                }else{
                    // 只有一个值时就是 =
                    $sql[] = "{$f} = ".$v[0];
                }

            }elseif (count($v) > 1){
                if($t == 'between'){
                    $sql[] = "{$f} between {$v[0]} and {$v[1]}";
                }else
                    $sql[] = "{$f} ".($t=='notin'?'not in':($t?:'in'))." (".implode(',',$v).")";
            }

        }else{
            if($f === '_'){
                $sql[] = $v;
            }else{
                $sql[] = "{$f} ".($t?:'=')." '". (is_string($v) ? addslashes($v): $v) ."'";
            }

        }

    }
    return implode(' '.$ar.' ',$sql);
}

/**
 * db 更新sql
 * @param array $data
 * @return string
 * @author:dc
 * @time 2023/2/17 10:43
 */
function dbUpdate(array $data):string {
    $sql = [];
    foreach ($data as $f=>$v){
        $sql[] = "`{$f}` = :{$f}";
    }
    return implode(' , ',$sql);
}


/**
 * 获取前端提交过来的邮箱
 * @return array
 * @throws \Lib\Err
 * @author:dc
 * @time 2023/3/10 14:57
 */
function web_request_emails():array {
    $emails = app()->request('emails');

    if(is_array($emails)){

    }elseif($emails && strpos($emails,',') > 0){
        $emails = explode(',',$emails);
    }else{
        $emails = [$emails];
    }

//    $emails = is_array($emails) ? $emails : [$emails];
    foreach ($emails as $k=>$email){
        if(!$email || !\Lib\Verify::sEmail($email)){
            unset($emails[$k]);
        }
    }

    if(empty($emails)){
        app()->e('email_request_required');
    }

    return array_values($emails);
}

/**
 * 前端获取邮箱一个
 * @return string
 * @throws \Lib\Err
 * @author:dc
 * @time 2023/3/10 16:05
 */
function web_request_email():string {
    $email = app()->request('email');

    if(!$email || !\Lib\Verify::sEmail($email)){
        app()->e('email_request_required');
    }

    return $email;
}




/**
 * 分页数据
 * @param $item
 * @param $total
 * @param $page
 * @param $limit
 * @return array
 * @author:dc
 * @time 2023/2/17 15:05
 */
function listsPage($item,$total,$page,$limit){
    return [
        'item'  =>  $item,
        'page'  =>  $page,
        'total'  =>  $total,
        'limit'  =>  $limit,
    ];
}




/**
 * 把返回的数据集转换成Tree
 * @param $list array 数据列表
 * @param string|int $pk 主键|root
 * @param string $pid 父id
 * @param string $child 子键
 * @param int $root 获取哪个id下面
 * @param bool $empty_child 当子数据不存在,是否要返回空子数据
 * @return array
 */
function list_to_tree($list, $pk='id',$pid = 'pid',$child = '_child',$root=0,$empty_child=true) {
    // 创建Tree
    $tree = array();
    if(is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            if($empty_child){
                $list[$key][$child] =   [];
            }
            $refer[$data[$pk]] =& $list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] =& $list[$key];
            }else{
                if (isset($refer[$parentId])) {
                    $refer[$parentId][$child][] =   & $list[$key];
                }
            }
        }
    }
    return $tree;
}


/**
 * todo:: 立即开始同步邮件,非必要请不要手动调用,,系统有定时调用,
 * @author:dc
 * @time 2023/2/18 11:04
 */
function start_now_mail(){
    $id = 0;

    while (true){
        $ids = db()->all('select `id` from `'.\Model\emailSql::$table.'` where `id` > '.$id.' order by `id` asc limit 1000 offset 0');
        if(!$ids){
            break;
        }
        foreach ($ids as $v){
            $id = $v['id'];
            redis()->rPush('sync_email_lists', $v['id']);
        }
    }

}

/**
 * @return string[]
 * @author:dc
 * @time 2023/4/13 11:02
 */
function folderAliasMap():array {
    return [
        'INBOX' =>  '收件箱',
        // qq的
        'Sent Messages' =>  '发件箱',
        'Sent' =>  '发件箱',
        'Drafts' =>  '草稿箱',
        'Junk' =>  '垃圾箱',
        'INBOX.Junk' =>  '垃圾箱',
        'Deleted Messages' =>  '回收站',
        'Trash' =>  '回收站',

        '垃圾邮件' =>  '垃圾箱',
        '已删除' =>  '回收站',
        '已删除邮件' =>  '回收站',
        '已发送' =>  '发件箱',
        '已发邮件' =>  '发件箱',
        'INBOX.Sent' =>  '发件箱',

//        'INBOX.Archive' =>  '归档',

        '垃圾桶' =>  '回收站',
        '垃圾郵件' =>  '垃圾箱',
        '寄件備份' =>  '发件箱',
        '草稿' =>  '草稿箱',

        //Gmail
        'Sent Mail' => '发件箱',
        'Starred' => '星标邮件',
        '已加星标' => '星标邮件',
        '已加星號' => '星标邮件',

    ];
}
/**
 * 固定文件夹的名称,统一
 * @param $folder
 * @return string
 * @author:dc
 * @time 2023/3/21 16:00
 */
function folderAlias(string $folder):string {

    $folder_map = folderAliasMap();

    foreach ($folder_map as $key=>$name){
        if(strtolower($folder) == strtolower($key)){
            return $name;
        }
    }


    return $folder_map[$folder]??$folder;

}


/**
 * true false
 * @param $val
 * @return bool
 * @author:dc
 * @time 2023/4/1 17:42
 */
function bool_Val($val):bool {
    if($val === 'true'){
        return true;
    }
    if($val === 'false'){
        return false;
    }

    if(is_numeric($val)){
        return intval($val) ? true : false;
    }

    return $val ? true : false;

}

/**
 * @param string $name
 * @return bool
 * @author:dc
 * @time 2023/4/15 16:50
 */
function paramHas(string $name):bool {
    return app()->requestHas($name);
}


/**
 * Sample text:
    $text = '<b>sample</b> text with <div>tags</div>';

    Result for strip_tags($text):
    sample text with tags

    Result for strip_tags_content($text):
    text with

    Result for strip_tags_content($text, '<b>'):
    <b>sample</b> text with

    Result for strip_tags_content($text, '<b>', TRUE);
    text with <div>tags</div>

    I hope that someone is useful :)
 * 删除html标记
 * @param $text
 * @param string $tags
 * @param false $invert
 * @return string|string[]|null
 * @author:dc
 * @time 2023/6/20 18:05
 */
function strip_tags_content($text, $tags = '', $invert = FALSE) {
    preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
    $tags = array_unique($tags[1]);
    if(is_array($tags) AND count($tags) > 0) {
        if($invert == FALSE) {
            return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?</\1>@si', '', $text);
        }
        else {
            return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?</\1>@si', '', $text);
        }
    }
    elseif($invert == FALSE) {
        return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
    }
    return $text;
}


/**
 * 返回邮件的uuid来区分是否是同一封邮件
 * @return string
 * @author:dc
 * @time 2023/9/18 9:33
 */
function get_email_uuid($subject,$udate,$form,$to,$size){

    return md5(json_encode([$subject,$udate,$form,$to,$size]));

}


/**
 * 转码
 * @param string $str
 * @param string $to
 * @param string|null $from
 * @return string
 * @author:dc
 * @time 2024/8/29 10:51
 */
function mb_iconv($str, $to, $from = null) {
    try {
        return mb_convert_encoding($str, $to, $from);
    }catch (Throwable $e){
        return $str;
    }
}




/**
 * 抛出异常
 * @param string $message
 * @throws Exception
 * @author:dc
 * @time 2024/9/26 9:46
 */
function abort(string $message = ''){
    throw new Exception($message);
}

/**
 * 加密base64
 * @param string $str
 * @return string 第一位是随机数长度 后N位是随机数 后面是加密的数字组合 统一个字符串的组合根据随机数的长度而定
 * @author:dc
 * @time 2024/12/20 11:21
 */
function base64_en_md5(string $str){
    $str = base64_encode($str);
    $r = rand(12,30); // TODO::随机数最低不能小于10
    $enStr = '*********************************************';
    $enStr = substr($enStr,0,$r).'0123456789+qwertyuiopasdfghjklzxcvbnm/QWERTYUIOPASDFGHJKLZXCVBNM';
    $enStr = str_split($enStr);
    foreach ($enStr as $k=>$e){
        if($e=='*'){
            unset($enStr[$k]);
        }
    }
    $enStr = array_flip($enStr);
    $strs = array_map(function ($v) use ($enStr){
        if($v=='='||$v==''){
            return '';
        }
        return $enStr[$v];
    },str_split($str));

    return (string) strlen((string) $r).$r.implode('',$strs);
}

/**
 * 解密 base64
 * @param string $str
 * @return false|string
 * @author:dc
 * @time 2024/12/20 11:51
 */
function base64_de_md5(string $str){
    $f = substr($str,0,1);
    $r = substr($str,1,$f);
    $enStr = '*********************************************';
    $enStr = substr($enStr,0,$r).'0123456789+qwertyuiopasdfghjklzxcvbnm/QWERTYUIOPASDFGHJKLZXCVBNM';
    $enStr = str_split($enStr);
    foreach ($enStr as $k=>$e){
        if($e=='*'){
            unset($enStr[$k]);
        }
    }

    $str = substr($str,$f+1);

    $strs = array_map(function ($v) use ($enStr){
        return $enStr[$v];
    },str_split($str,$f));

    return base64_decode(implode('',$strs).'==');

}


/**
 * 把最大最小之间的数生成 二维数组
 * [[2,3,4],[5,6,7],....]
 * @param $min
 * @param $max
 * @param int $len
 * @return array
 * @author:dc
 * @time 2025/3/7 0:06
 */
function minMaxToArray($min, $max,$len=1000) {
    $result = [];
    $currentGroup = [];

    for ($i = $min; $i <= $max; $i++) {
        $currentGroup[] = $i;

        // 每1000个数就创建一个新组
        if (count($currentGroup) == $len) {
            $result[] = $currentGroup;
            $currentGroup = []; // 重置当前组
        }
    }

    // 如果还有剩余的数,添加到结果中
    if (!empty($currentGroup)) {
        $result[] = $currentGroup;
    }

    return $result;
}

/**
 * es
 * @return \Lib\Es\Es
 * @author:dc
 * @time 2025/3/8 23:13
 */
function es(){
    return (new Lib\Es\Es('email_ai_emails',['https://ai-email:3mLbEKwDX9YjUDFm@172.19.0.56:9200']));
}