<?php
namespace app\mobile\service;

use think\facade\Cache;
use think\facade\Db;

/** 只缓存条款与名称字典；人员权限、点检记录、设备状态和暂停状态始终实时查询。 */
class CheckCatalog
{
    private static function key() {
        $c=Db::connect()->getConfig();
        return 'oms-check-catalog:v1:'.hash('sha256',$c['database'].':'.$c['prefix']);
    }
    private static function remember($part,$load) {
        $cache=Cache::store('redis');$base=self::key();$generation=$cache->get($base.':generation')?:'0';
        $key=$base.':'.$generation.':'.$part;$entry=$cache->get($key);
        if(is_array($entry) && $entry['refreshAt']>time())return $entry['value'];
        // 过软有效期时一人刷新，其余人立即读旧值；硬过期时才等待冷启动。
        $lock='oms-check-catalog:'.substr(hash('sha256',$key),0,40);
        $got=Db::query('SELECT GET_LOCK(?,?) acquired',[$lock,is_array($entry)?0:5]);
        if((int)$got[0]['acquired']!==1){
            if(is_array($entry))return $entry['value'];
            throw new \RuntimeException('点检条款缓存正在初始化，请稍后重试');
        }
        try {
            $entry=$cache->get($key);
            if(!is_array($entry) || $entry['refreshAt']<=time()){$entry=['value'=>$load(),'refreshAt'=>time()+60];$cache->set($key,$entry,300);}
            return $entry['value'];
        } finally {Db::query('SELECT RELEASE_LOCK(?)',[$lock]);}
    }
    public static function clauses($type,$fresh=false) {
        $type=(int)$type;
        $load=function()use($type){return Db::name('me_check_list')->where(['type'=>$type,'status'=>1])->order('order,id')->select()->toArray();};
        return $fresh?$load():self::remember('type-'.$type,$load);
    }
    public static function names() {
        return self::remember('names-v2',function(){return ['types'=>Db::name('me_base')->column('title','id'),'lines'=>Db::name('team_base')->column('title','id'),'lineProjects'=>Db::name('team_base')->alias('l')->leftJoin('team_base p','p.id=l.mark AND p.mid=1')->where('l.mid',2)->column('p.title','l.id')];});
    }
    public static function invalidate() {Cache::store('redis')->set(self::key().':generation',bin2hex(random_bytes(8)));}
}
