<?php
namespace app\common\model;

use think\Db;
use think\Cache;

class VodSearch extends Base {
    // 设置数据表（不含前缀）
    protected $name = 'vod_search';
    // 最大Id数量，使用IN查询时，超过一定数量，查询不使用索引了
    public $maxIdCount = 1000;
    private $updateTopCount = 50000;


    /**
     * 获取结果Id列表
     */
    public function getResultIdList($search_word, $search_field, $word_multiple = false)
    {
        $search_word = trim($search_word);
        $search_word = str_replace(',,', '', $search_word);
        if (strlen($search_word) == 0 || strlen($search_field) == 0) {
            return [];
        }
        // 如果包含多个关键词，使用递归处理
        if ($word_multiple === true) {
            $id_list = [];
            $search_word_exploded = explode(',', $search_word);
            foreach ($search_word_exploded as $search_word) {
                $id_list += $this->getResultIdList($search_word, $search_field);
            }
            $id_list = array_unique($id_list);
            return $id_list;
        }
        $search_key = md5($search_word . '@' . $search_field);
        $where = ['search_key' => $search_key];
        $search_row = $this->where($where)->field("search_result_ids, search_hit_count")->find();
        if (empty($search_row)) {
            $where_vod = [];
            $where_vod[$search_field] = ['LIKE', '%' . $search_word . '%'];
            $id_list = Db::name('Vod')->where($where_vod)->order("vod_id ASC")->column("vod_id");
            $id_list = is_array($id_list) ? $id_list : [];
            $this->insert([
                'search_key'           => $search_key,
                'search_word'          => mb_substr($search_word, 0, 128),
                'search_field'         => mb_substr($search_field, 0, 64),
                'search_hit_count'     => 1,
                'search_last_hit_time' => time(),
                'search_update_time'   => time(),
                'search_result_count'  => count($id_list),
                'search_result_ids'    => join(',', $id_list),
            ]);
        } else {
            $id_list = explode(',', (string)$search_row['search_result_ids']);
            $id_list = array_filter($id_list);
            $this->where($where)->update([
                'search_hit_count'     => $search_row['search_hit_count'] + 1,
                'search_last_hit_time' => time(),
            ]);
        }
        $id_list = array_map('intval', $id_list);
        $id_list = empty($id_list) ? [0] : $id_list;
        return $id_list;
    }

    /**
     * 前端是否开启
     */
    public function isFrontendEnabled()
    {
        $config = config('maccms');
        // 未设置时，默认关闭
        if (!isset($config['app']['vod_search_optimise'])) {
            return false;
        }
        $list = explode('|', $config['app']['vod_search_optimise']);
        return in_array('frontend', $list);
    }

    /**
     * 采集是否开启
     */
    public function isCollectEnabled()
    {
        $config = config('maccms');
        // 未设置时，默认关闭
        if (!isset($config['app']['vod_search_optimise'])) {
            return false;
        }
        $list = explode('|', $config['app']['vod_search_optimise']);
        return in_array('collect', $list);
    }

    /**
     * 检查更新搜索结果
     */
    public function checkAndUpdateTopResults($vod, $force = false)
    {
        static $list;
        if (empty($vod['vod_id'])) {
            return;
        }
        if (is_null($list)) {
            $cach_name = 'vod_search_top_result_v2_' . $this->updateTopCount;
            $list = $force ? [] : Cache::get($cach_name);
            if (empty($list)) {
                $list = $this->field("search_key, search_word, search_field")->order("search_hit_count DESC, search_last_hit_time DESC")->limit("0," . $this->updateTopCount)->select();
                $force === false && Cache::set($cach_name, $list, count($list) < ($this->updateTopCount / 10) ? 3600 : 86400);
                $this->clearOldResult();
            }
        }
        $time_now = time();
        foreach ($list as $row) {
            foreach (explode('|', $row['search_field']) as $field) {
                if (!isset($vod[$field]) || strlen($vod[$field]) == 0) {
                    continue;
                }
                if (stripos($vod[$field], $row['search_word']) === false) {
                    continue;
                }
                Db::execute("UPDATE `" . config('database.prefix') . $this->name . "` SET 
                    search_update_time='{$time_now}',
                    search_result_count=search_result_count+1,
                    search_result_ids=CONCAT(search_result_ids,',','{$vod['vod_id']}')
                WHERE search_key='{$row['search_key']}'");
            }
        }
    }

    /**
     * 获取结果缓存的分钟数，后台配置覆盖默认值
     */
    public function getResultCacheMinutes($config = []) {
        // 默认14天
        $minutes = 20160;
        $config = $config ?: config('maccms');
        if (isset($config['app']['vod_search_optimise_cache_minutes']) && (int)$config['app']['vod_search_optimise_cache_minutes'] > 0) {
            $minutes = (int)$config['app']['vod_search_optimise_cache_minutes'];
        }
        return $minutes;
    }

    /**
     * 清理老的数据
     */
    public function clearOldResult($force = false) 
    {
        // 清理多久前的
        $clear_seconds = $this->getResultCacheMinutes() * 60;
        // 设置间隔，每天最多清理1次
        $cach_name = 'interval_vs_clear_old_v1_' . $clear_seconds;
        $cache_data = Cache::get($cach_name);
        if ($force === false && !empty($cache_data)) {
            return;
        }
        Cache::set($cach_name, 1, min($clear_seconds, 86400));
        // vod_actor在采集的时候可提高效率，暂不清理
        $where = [
            'search_field'       => ['neq', 'vod_actor'],
            'search_update_time' => ['lt', time() - $clear_seconds],
        ];
        // 后台强制清理时，都清掉
        if ($force === true) {
            unset($where['search_field']);
        }
        $this->where($where)->delete();
    }

}
