<?php


namespace App\Libs;


use App\Cache\CacheKeys;
use App\Exceptions\ApiException;
use Hashids;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class Utils
{
    /**
     * 异常报错
     * @param       $errorData
     * @throws ApiException
     */
    public static function throwError($errorData)
    {
        // 分解错误码、错误信息
        $arr  = explode(':', (string)$errorData);
        $code = (int)$arr[0];
        $msg  = (string)$arr[1];

        throw new ApiException($code, $msg);
    }

    /**
     * 解码加密id
     * @param $idStr
     * @return int
     */
    public static function getDecodeId($idStr)
    {
        if (!is_numeric($idStr)) {
            $idArr = Hashids::decode($idStr);
            $id    = isset($idArr[0]) ? (int)$idArr[0] : 0;
        } else {
            $id = $idStr;
        }

        return $id;
    }

    /**
     * 加密id
     * @param $id
     * @return mixed
     */
    public static function getEncodeId($id)
    {
        return Hashids::encode($id);
    }

    /**
     * 加密批量bid
     * @param $bids
     * @return array
     */
    public static function getEncodeIds($bids)
    {
        return array_map(function ($bid) {
            return Hashids::encode($bid);
        }, $bids);
    }

    /**
     * 审核状态判断，true为审核状态，false默认
     * @param $package
     * @param $brand
     * @param $codeVersion
     * @return bool
     */
    public static function checkIsAudit($package, $brand, $codeVersion): bool
    {
        $audit = getProp(config('audit'), $package, []);
        if ($audit && $codeVersion === getProp($audit, 'codeVersion') && strtolower($brand) === getProp($audit, 'brand')) {
            return true;
        }

        return false;
    }

    /**
     * redis key组装
     * @param $keyStr
     * @param $args
     * @return string
     */
    public static function getCacheKey($keyStr, $args = [])
    {
        $stdStr = Arr::get(CacheKeys::$all, $keyStr, '');
        if ($args) {
            $stdStr = sprintf($stdStr, ...$args);
        }

        return $stdStr;
    }

    /**
     * 展示友好数字
     * @param $num
     * @return string
     */
    public static function showNiceNumber($num)
    {
        if ($num >= 10000) {
            $num = sprintf('%.1f', round($num / 10000 * 100) / 100) . '万';
        } elseif ($num >= 1000) {
            $num = sprintf('%.1f', round($num / 1000 * 100) / 100) . '千';
        }
        return $num;
    }

    /**
     * 根据日期获得这周的周一
     * @param        $date
     * @param int    $d
     * @param string $format
     * @return false|string
     */
    public static function firstOfWeek($date, $d = 0, $format = 'Ymd')
    {
        $now      = strtotime($date) - $d * 86400;    //当时的时间戳
        $number   = date("w", $now);  //当时是周几
        $number   = $number == 0 ? 7 : $number; //如遇周末,将0换成7
        $diff_day = $number - 1; //求到周一差几天
        return date($format, $now - ($diff_day * 60 * 60 * 24));
    }

    /**
     * 老原创的签名
     * @param $time
     * @return string
     */
    public static function getOldYcSign($time): string
    {
        $privateKey = env('EXTERNAL_PRIVATE_KEY');
        return md5(md5($time . $privateKey) . $privateKey);
    }

    /**
     * @param array $data
     * @param array $colHeaders
     * @param bool  $asString
     * @return bool|string
     */
    public static function toCSV(array $data, array $colHeaders = array(), $asString = false)
    {
        $stream = $asString ? fopen('php://temp/maxmemory', 'wb+') : fopen('php://output', 'wb');

        if (!empty($colHeaders)) {
            fputcsv($stream, $colHeaders);
        }

        foreach ($data as $record) {
            fputcsv($stream, $record);
        }

        if ($asString) {
            rewind($stream);
            $returnVal = stream_get_contents($stream);
            fclose($stream);
            return $returnVal;
        }

        fclose($stream);
        return true;
    }

    /**
     * 设备信息
     * @return string
     */
    public static function getDeviceType(): string
    {
        //全部变成小写字母
        $agent = strtolower(getProp($_SERVER, 'HTTP_USER_AGENT'));
        $type  = 'other';
        //分别进行判断
        if (strpos($agent, 'iphone') || strpos($agent, 'ipad')) {
            $type = 'ios';
        }

        if (strpos($agent, 'android')) {
            $type = 'android';
        }
        return $type;
    }

    /**
     * 是否在微信内打卡
     * @return bool
     */
    public static function isOpenedInWechat(): bool
    {
        //全部变成小写字母
        $agent = strtolower($_SERVER['HTTP_USER_AGENT']);

        //判断
        if (strpos($agent, 'micromessenger')) {
            return true;
        }

        return false;
    }

    /**
     * 组装meta数据
     * @param     $page
     * @param     $total
     * @param int $pageSize
     * @return array
     */
    public static function buildMeta($page, $total, $pageSize = 15): array
    {
        $lastPage = (int)ceil($total / $pageSize);
        return [
            'current_page'  => (int)$page,
            'next_page'     => ++$page,
            'last_page'     => $lastPage ?? 1,
            'per_page'      => (int)$pageSize,
            'total'         => (int)$total,
            'next_page_url' => '',
            'prev_page_url' => ''
        ];
    }

    /**
     * 获取token保存的信息
     * @param $token
     * @return mixed
     */
    public static function getTokenData($token) {
        $tokenJson = Redis::get($token);
        return json_decode($tokenJson, true);
    }

    /**
     * 获取口令码
     * @param $uid
     * @param $bid
     * @return int|mixed|null
     */
    public static function getPasswordCode($uid, $bid) {
        $code = DB::table('user_book_code')->where(['uid'=>$uid, 'bid'=>$bid])->value('id');
        if (!$code) {
            $code = DB::table('user_book_code')->insertGetId([
                'uid'           => $uid,
                'bid'           => $bid,
                'created_at'    => date('Y-m-d H:i:s'),
                'updated_at'    => date('Y-m-d H:i:s'),
            ]);
        }
        return '请在抖音搜索“火猫小说”后搜索口令'.$code.'，开始阅读吧！';
    }
}
