<?php

namespace app\service;

use app\entity\SysDictionary;
use think\facade\Cache;
use think\Service;

/**
 * 字典服务
 */
class DictionaryService extends Service
{
    readonly protected array $sysDictData;

    public function register(): void
    {
        /*
         * 注册到全局容器中
         */
        $this->app->bind('dict', $this);
        /*
         * 添加应用事件初始化字典内容
         */
        $this->app->event->listen("AppInit", function () {
            $this->sysDictData = Cache::remember('sysDict', function () {
                $array = [];
                SysDictionary::with(['dictData'])->select()->each(function (SysDictionary|\app\model\SysDictionary $dict) use (&$array) {
                    $array[$dict->dict_code] = $dict->dictData->column('dict_data_name', 'dict_data_code');
                });
                return $array;
            }, 3600 * 4);
        });
    }

    /**
     * 获取字典
     * @param string $name
     * @param $default
     * @param $cache
     * @return mixed
     */
    public function get(string $name, $default = null, $cache = true)
    {
        if (!$cache) {
            return $this->getValue($name, $default);
        } else {
            /*
             * 通过缓存判断减少计算操作(使用内存换取性能)
             */
            static $cacheValue = [];
            if (!isset($cacheValue[$name]) || $cacheValue[$name]['0'] !== $default) {
                $cacheValue[$name] = ['v' => $this->getValue($name, $default), '0' => $default];
            }
            return $cacheValue[$name]['v'];
        }
    }

    /**
     * 获取字典元素
     * @param string $name
     * @param $default
     * @return mixed
     */
    private function getValue(string $name, $default = null): mixed
    {
        $keys = explode('.', $name);
        if (count($keys) == 1) {
            return $this->sysDictData[$name] ?? (is_array($default) ? $default : []);
        }
        $code = array_pop($keys);
        $key = implode('.', $keys);
        if (isset($this->sysDictData[$key])) {
            return $this->sysDictData[$key][$code] ?? $default;
        }
        return $default;
    }

    public function clearCache()
    {
        Cache::delete('sysDict');
    }
}