<?php

namespace app\common\arw\adjfut\src;

use DateTime;
use think\facade\Log;
use think\helper\Arr;
use app\common\arw\adjfut\src\Exception\ErrorMsg;

class Tool
{
    /**
     * 生成配置项
     *
     * @param array $config
     * @param callable|string $cb 自定义合并策略
     * @return callable
     * @date 2022-07-29
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function generateConfig(array $config, $cb = 'array_merge'): callable
    {
        return function (...$argv) use ($cb, $config) {
            array_unshift($argv, $config);
            return call_user_func_array($cb, $argv);
        };
    }

    /**
     * 构建url
     *
     * @param string $url
     * @param array $query
     * @param boolean $decode
     * @return string
     * @date 2023-01-04
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function buildUrl(string $url, array $query = [], bool $decode = true): string
    {
        $parse = parse_url($url);
        $parse_query = Arr::get($parse, 'query', '');
        $_query = [];
        parse_str($parse_query, $_query);
        if (!is_array($_query)) {
            $_query = [];
        }
        $_query = array_merge($_query, $query);
        $_url = str_replace('?' . $parse_query, '', $url);
        $_url .= '?';
        $_url .= http_build_query($_query);
        if ($decode) {
            $_url = urldecode($_url);
        }
        return $_url;
    }

    /**
     * 写入通道日志
     *
     * @param string $channel
     * @param string $type
     * @param array $data
     * @return void
     * @date 2022-07-29
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function writeChannelLog(string $channel, string $type, array $data): void
    {
        Log::channel($channel)->$type(json_encode($data, JSON_UNESCAPED_UNICODE));
    }

    /**
     * 字段映射
     *
     * @param array $data
     * @param array $map
     * @param array $options
     * @return array
     * @date 2022-06-23
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function fieldMap(array $data, array $map, array $options = []): array
    {
        $prefix = Arr::get($options, 'prefix', '');
        $result = [];
        foreach ($data as $key => $value) {
            if (isset($map[$key])) {
                $key = $map[$key];
            }
            if ($prefix) {
                $key = $prefix . $key;
            }
            $result[$key] = $value;
        }
        return $result;
    }

    /**
     * 转换日期格式
     *
     * @param string $datetime
     * @param string $format
     * @return string
     * @date 2022-04-20
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function conversionDateTime($datetime, string $format): string
    {
        try {
            $date = new DateTime($datetime);
            return $date->format($format);
        } catch (\Throwable $th) {
            throw new ErrorMsg('日期格式非法', 1);
        }
    }

    /**
     * 生成唯一id
     *
     * @param string|array $value
     * @return string
     * @date 2022-03-24
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function generateGuid($value = ''): string
    {
        $str = '';
        if (is_array($value)) {
            $str = json_encode($value);
        }
        $charid = strtolower(md5($str . uniqid('', true)));
        $hyphen = chr(45); // '-'
        $uuid = //chr(123)// '{'
            substr($charid, 0, 8) . $hyphen
            . substr($charid, 8, 4) . $hyphen
            . substr($charid, 12, 4) . $hyphen
            . substr($charid, 16, 4) . $hyphen
            . substr($charid, 20, 12);
        //.chr(125);// '}'
        return $uuid;
    }


    /**
     * 清空（擦除）缓冲区并关闭输出缓冲
     *
     * @return void
     */
    public static function obEndClean(): void
    {
        try {
            while (ob_get_level() > 0) {
                ob_end_clean();
            }
        } catch (\Throwable $th) {
            //throw $th;
        }
    }

    /**
     * 自动创建文件夹
     *
     * @param string $path 文件夹路径
     * @param integer $mode 权限
     * @return boolean
     */
    public static function mkdir(string $path, int $mode = 0755): bool
    {
        $path = str_replace('/', DIRECTORY_SEPARATOR, $path);
        $temp = explode(DIRECTORY_SEPARATOR, $path);
        if (preg_match("/\./", end($temp))) {
            // pathinfo 不支持中文
            // $path = pathinfo($path, PATHINFO_DIRNAME);
            array_splice($temp, count($temp) - 1, 1);
            $path = join(DIRECTORY_SEPARATOR, $temp);
        }
        if (!file_exists($path)) {
            mkdir($path, $mode, true);
        }
        chmod($path, $mode);
        return true;
    }
}
