<?php

namespace app\extra\service\system;

use app\extra\basic\Service;
use app\model\system\SystemConfig;
use app\model\system\SystemData;
use app\model\system\SystemOplog;
use support\think\Cache;

class SystemService extends Service
{

    /**
     * 配置缓存数据
     * @var array
     */
    private static array $config = [];


    public static function get(string $name = '', string $default = '')
    {
        try {
            $cacheConfig = Cache::get("SystemConfig");
            if (empty($cacheConfig))
            {
                $config = (new SystemConfig)->select();
                self::setConfig($config);
                Cache::set("SystemConfig",json_encode($config));
            } else {
                $config = json_decode($cacheConfig,true);
                self::setConfig($config);
            }

            [$type, $field, $outer] = static::_parse($name);
            if (empty($name)) {
                return static::$config;
            } elseif (isset(static::$config[$type])) {
                $group = static::$config[$type];
                if ($outer !== 'raw') foreach ($group as $kk => $vo) {
                    $group[$kk] = htmlspecialchars(strval($vo));
                }
                return $field ? ($group[$field] ?? $default) : $group;
            } else {
                return $default;
            }

        } catch (\Exception $exception)
        {
            return false;
        }

    }

    protected static function setConfig($data)
    {
        foreach($data as $item)
        {
            static::$config[$item['type']][$item['name']] = $item['value'];
        }
    }

    public static function set(string $name, $value = '')
    {
        static::$config = [];
        [$type, $field] = static::_parse($name);
        if (is_array($value)) {
            $count = 0;
            foreach ($value as $kk => $vv) {
                $count += static::set("{$field}.{$kk}", $vv);
            }
            return $count;
        } else try {
            Cache::delete("SystemConfig");
            $map = ['type' => $type, 'name' => $field];
            $data = array_merge($map, ['value' => $value]);
            $query = (new SystemConfig)->where($map);
            return (clone $query)->count() > 0 ? $query->update($data) : $query->insert($data);
        } catch (\Throwable $exception) {
            return false;
        }
    }

    /**
     * 解析缓存名称
     * @param string $rule 配置名称
     * @return array
     */
    private static function _parse(string $rule): array
    {
        $type = 'base';
        if (stripos($rule, '.') !== false) {
            [$type, $rule] = explode('.', $rule, 2);
        }
        [$field, $outer] = explode('|', "{$rule}|");
        return [$type, $field, strtolower($outer)];
    }


    /**
     * 读取数据内容
     * @param string $name
     * @param array $default
     * @return array|mixed
     */
    public static function getData(string $name, array $default = [])
    {
        try {
            $value = (new SystemData)->where("name",$name)->value("content");
            if (!empty($value)) return json_decode($value,true);
            return $default;
        } catch (\Throwable $exception)
        {
            return $default;
        }
    }

    /**
     * 保存数据内容
     * @param string $name 数据名称
     * @param mixed $value 数据内容
     * @return bool
     */
    public static function setData(string $name, $value)
    {
        try {
            $data = ['name' => $name, 'content' => json_encode($value, 64 | 256)];
            return (new SystemData)->setAutoData($data,"name");
        } catch (\Throwable $exception) {
            echo $exception->getFile()."\n";
            echo $exception->getLine()."\n";
            echo $exception->getMessage()."\n";
            return false;
        }
    }


    /**
     * 写入系统日志内容
     * @param string $action
     * @param string $content
     * @param string $userName
     * @return boolean
     */
    public static function setOplog(string $action, string $content, string $userName): bool
    {
        return (new SystemOplog)->insert(static::getOplog($action, $content,$userName)) !== false;
    }

    /**
     * 获取系统日志内容
     * @param string $action
     * @param string $content
     * @param string $userName
     * @return array
     */
    public static function getUserOplog(string $action, string $content, string $userName): array
    {
        return [
            'username'  => $userName,
            'action'    => $action, 'content' => $content,
            'geoip'     => request()->getRealIp() ?: '127.0.0.1',
        ];
    }

    /**
     * 获取系统日志内容
     * @param string $action
     * @param string $content
     * @param string $userName
     * @return array
     */
    public static function getOplog(string $action, string $content, string $userName): array
    {
        return [
            'node'      => request()->uri(),
            'action'    => $action, 'content' => $content,
            'geoip'     => request()->getRealIp() ?: '127.0.0.1',
            'username'  => $userName ?: '-'
        ];
    }

}