<?php

namespace app\extra\basic;

use app\extra\tools\CodeExtend;
use app\model\system\SystemUser;
use think\contract\Arrayable;
use think\Validate;

class Base
{


    const DEFAULT_SUCCESS_MESSAGE = 'success';
    const DEFAULT_FAIL_MESSAGE = 'fail';

    const DEFAULT_SUCCESS_CODE = 200;
    const DEFAULT_FAIL_CODE = 400;


    protected function getParent(array $data)
    {
        if ($data['parent_id'] > 0) {
            return $data['parent_id'];
        }
        return $data['user_id'];
    }

    public function getShopId()
    {
        return request()->header("shop",0);
    }

    public function getAccountId(array $data)
    {
        return $data['account_id'];
    }

    protected function getDyConfig(): array
    {
        return ["appid" => sConf('dy.appid'),'secret' => sConf('dy.secret')];
    }

    /**
     * 写入新用户
     * @param array $param
     * @return bool
     */
    protected function sceneUser(array $param = [],int $type = 1,$field = "agent_id"): bool
    {
        if (!isset($param['id']))
        {
            $param['salt'] = strtoupper(CodeExtend::random(10,3));
            $param['password'] = md5($param['password'].$param['salt']);
            $param['create_ip'] = request()->getRealIp() ?: '127.0.0.1';
            $param['type'] = $type;
        }
        return (new SystemUser)->setAutoData($param,$field);
    }

    protected function getSmsChannel(): array
    {
        return [
            [
                "name"  => "阿里云",
                "type"  => "aliyun",
                "url"   => "https://dysms.console.aliyun.com/dysms.htm"
            ],
            [
                "name"  => "腾讯云",
                "type"  => "qcloud",
                "url"   => "https://console.cloud.tencent.com/smsv2"
            ],
            [
                "name"  => "七牛云",
                "type"  => "qiniu",
                "url"   => "https://portal.qiniu.com/sms/dashboard"
            ]
        ];
    }

    /**
     *  快捷输入并验证（ 支持 规则 # 别名 ）
     * @param array $rules 验证规则（ 验证信息数组 ）
     * @param array|string $input 输入方式 ( post. 或 get. )
     * @param callable|null $callable 异常处理操作
     */
    protected function _valid(array $rules, array|string $input = '', ?callable $callable = null)
    {
        if (is_string($input)) {
            $type = trim($input, '.') ?: 'get';
            $input = request()->$type();
        }
        [$data, $rule, $info] = [[], [], []];
        foreach ($rules as $name => $message) if (is_numeric($name)) {
            [$name, $alias] = explode('#', $message . '#');
            $data[$name] = $input[($alias ?: $name)] ?? null;
        } elseif (!str_contains($name, '.')) {
            $data[$name] = $message;
        } elseif (preg_match('|^(.*?)\.(.*?)#(.*?)#?$|', $name . '#', $matches)) {
            [, $_key, $_rule, $alias] = $matches;
            if (in_array($_rule, ['value', 'default'])) {
                if ($_rule === 'value') $data[$_key] = $message;
                elseif ($_rule === 'default') $data[$_key] = $input[($alias ?: $_key)] ?? $message;
            } else {
                $info[explode(':', $name)[0]] = $message;
                $data[$_key] = $data[$_key] ?? ($input[($alias ?: $_key)] ?? null);
                $rule[$_key] = isset($rule[$_key]) ? ($rule[$_key] . '|' . $_rule) : $_rule;
            }
        }
        $validate = new Validate();
        if ($validate->rule($rule)->message($info)->check($data)) {
            return $data;
        } elseif (is_callable($callable)) {
            return call_user_func($callable, $validate->getError(), $data);
        } else {
            return $validate->getError();
        }
    }


    /**
     * @param $data
     * @return array|string|null
     */
    private function parseData($data)
    {
        if ($data instanceof Arrayable)
            return $data->toArray();
        else
            return $data;
    }

    /**
     * @param string|array|Arrayable $message
     * @param array|Arrayable|null $data
     * @return Json
     */
    public function success($message = self::DEFAULT_SUCCESS_MESSAGE, $data = null)
    {
        $message = $this->parseData($message);
        if (is_array($message)) {
            $data = $message;
            $message = self::DEFAULT_SUCCESS_MESSAGE;
        } else {
            $data = $this->parseData($data);
        }
        return $this->make(self::DEFAULT_SUCCESS_CODE, $message, $data);
    }


    /**
     * @param int $status
     * @param string $message
     * @param array|Arrayable|null $data
     */
    public function make(int $status, string $message, $data = null)
    {
        $content = compact('status', 'message');
        if (!is_null($data))
            $content['data'] = $this->parseData($data);
        return json($content);
    }

    public function encode($message = self::DEFAULT_SUCCESS_MESSAGE, $data = null)
    {
        $message = $this->parseData($message);
        if (is_array($message)) {
            $data = $message;
            $message = self::DEFAULT_SUCCESS_MESSAGE;
        } else {
            $data = $this->parseData($data);
        }
        $status = self::DEFAULT_SUCCESS_CODE;
        $encode = true;
        $content = compact('status','encode', 'message');
        if (is_null($data) || env('APP_DEBUG', false))
            return $this->success($message, $data['data'] ?? $data);
        if (!is_array($data) || !isset($data['data'])) {
            $res['data'] = $data;
        } else {
            $res = $data;
        }
        $res['status'] = $status;
        $res['message'] = $message;
        $content['data'] =  base64_encode(gzdeflate(json_encode($res,JSON_UNESCAPED_UNICODE),9));
        return json($content);
    }


    /**
     * 菜单信息格式化
     * @param array $menus
     * @param int $type
     * @param int $mch
     * @return array
     */
    protected function filterMenu(array $menus,int $type,int $mch = 0): array
    {
        foreach ($menus as &$menu) {
            $menu['meta'] = [
                "title"     => $menu['title'],
                "icon"      => $menu['icon']??'',
                "type"      => $menu['type']
            ];
            if (!empty($menu['children'])) {
                $menu['children'] = $this->filterMenu($menu['children'],$type,$mch);
            }
            if ($mch > 0) {
                $menu['component'] = ($mch==1?'merchant/':'store/').$menu['name'];
            } else {
                $menu['component'] = $menu['name'];
            }
            $menu['isMenu'] = $menu['status'];
            if($type == 1) unset($menu['title'],$menu['icon'],$menu['type'],$menu['pid'],$menu['id']);
        }
        return $menus;
    }



}