<?php
/**
 * Copyright: Shanghai NuLang Network Technology Co., Ltd.
 * Faith: Some things do not need others to understand.
 * Project: CoverCMS <Your world, your ambition>
 * License: http://www.svipplus.cn/license/
 * Author: The Rain° <rain@svipplus.cn>
 * File: CoverTwigExtension.php
 * Time: 12:34
 */

namespace covercms\bridge\twig;


use app\common\toolKit\CommonKit;
use app\common\toolKit\SiteKit;
use think\Db;
use Twig\TwigFunction;

class CoverTwigExtension extends \Twig_Extension
{
    public function getFunctions()
    {
        return [
            new TwigFunction('asset', [$this, 'asset']),
            new TwigFunction('cover', [$this, 'cover']),
            new TwigFunction('arc', [$this, 'archive']),
            new TwigFunction('url',[$this,'url'])
        ];
    }

    public function asset($path = '')
    {
        return request()->root() . '/resources/asset/' . $path;
    }

    public function url($url = '', $vars = '', $suffix = true, $domain = false)
    {
        return url($url,$vars,$suffix,$domain);
    }

    public function archive($tag, array $params = [])
    {
        $tagIsTable = true;
        $table = '';
        $categoryId = 0;
        if (is_string($tag)) {
            $table = $tag;
        } else {
            $tagIsTable = false;
            $categoryId = intval($tag);
            if ($categoryId === 0) {
                return [];
            }
            $currentCat = Db::name('category')->where('id', $categoryId)->find();
            $currentCatCType = intval($currentCat['c_type']);
            $table = CommonKit::getModelByCType($currentCatCType);
        }
        if ($table == 'link' || $table == 'single') {
            return [];
        }
        $condition = [];
        $num = 10;
        if (isset($params['num']) && intval($params['num']) > 0) {
            $num = intval($params['num']);
        }
        $start = 0;
        if (isset($params['start'])) {
            $start = intval($params['start']);
        }
        $order = 'weight desc';
        if (isset($params['order'])) {
            $order = $params['order'];
        }
        $order .= ',create_time desc';
        if ($categoryId !== 0) {
            $condition['category_id'] = $categoryId;
        } elseif (isset($params['category_id']) && intval($params['category_id']) !== 0) {
            $condition['category_id'] = intval($params['category_id']);
        }
//        $condition['recom'] = 0;
        if (isset($params['recom'])) {
            $condition['recom'] = intval($params['recom']);
        }
//        $condition['top'] = 0;
        if (isset($params['top'])) {
            $condition['top'] = intval($params['top']);
        }
        $rst = Db::name($table)->where($condition)->limit($start, $num)->order($order)->select();
        if ($rst && count($rst)>0){
            foreach ($rst as &$item){
                if (isset($item['link']) && !empty(trim($item['link']))){
                    $item['url'] = $item['link'];
                }else{
                    $item['url'] = url('detail',['cid'=>$item['category_id'],'aid'=>$item['id']]);
                }
            }
        }
        return $rst;
    }

    public function cover($tag, $params = '')
    {
        $tag = strtolower(trim($tag));
        if (method_exists(new static(), $tag)) {
            return self::$tag($params);
        } else {
            return '';
        }
    }


    public function category($param = [])
    {
        if (isset($param['self']) && isset($param['id'])){
            $cat = CommonKit::getCategoryByCategoryId(intval($param['id']));
            return $cat;
        }
        $parentId = 0;
        if (isset($param['parent_id'])) {
            $parentId = intval($param['parent_id']);
        }
        $hasExcept = false;
        $except = 0;
        if (isset($param['except'])) {
            $except = intval($param['except']);
        }
        if ($except !== 0) {
            $hasExcept = true;
        }
        $condition['parent_id'] = $parentId;
        $order = 'weight desc';
        if (isset($param['order']) && !empty(trim($param['order']))) {
            $order = trim($param['order']);
        }
        if (isset($param['limit']) && intval($param['limit'])>0){
            $all = Db::name('category')->where($condition)->limit(intval($param['limit']))->order($order)->select();
        }else{
            $all = Db::name('category')->where($condition)->order($order)->select();
        }
        if (!$all) {
            return [];
        }
        $siteInfo = SiteKit::currentSiteInfo();
        $siteDomain = $siteInfo['domain'];
        if (stripos($siteDomain, 'localhost') || stripos($siteDomain, '127.0.0.1')) {
            $siteDomain = 'http://localhost';
        }
        $finalResult = [];
        if (count($all) > 0) {
            $urlParam['cid'] = 0;
            foreach ($all as $item) {
                if (!$item['is_show']){
                    continue;
                }
                if ($hasExcept && $item['id'] === $except) {
                    continue;
                }
                $cTypeMark = $item['c_type'];
                $cType = CommonKit::getModelByCType($cTypeMark);
                $action = 'channel';
                $urlParam['cid'] = $item['id'];
                if ($cType == 'link') {
                    array_push($finalResult,$item);
                    continue;
                }
                if (!$item['has_children']) {
                    $action = 'list';
                }
                if ($cType == 'single') {
                    $action = 'single';
                    if ($item['has_children']) {
                        $maxWeightSonId = $this->findMaxWeightSonId(intval($item['id']));
                        $urlParam['cid'] = $maxWeightSonId;
                    }
                }
                $url = url('app/default/' . $action, $urlParam, true, $siteDomain);
                $item['url'] = $url;
                array_push($finalResult, $item);
            }
        }
        return $finalResult;
    }

    private function findMaxWeightSonId($parentId)
    {
        $directSons = Db::name('category')->field('id,weight')->order('weight desc')->where('parent_id', intval($parentId))->select();
        return $directSons[0]['id'];
    }


    private function block(array $params)
    {
        if (isset($params['block'])) {
            $item = Db::name('block')->where('tag', $params['block'])->find();
            if (!$item || empty(trim($item['var']))) {
                return '';
            }
            $fieldType = $item['field_type'];
            $var = '';
            switch ($fieldType) {
                case 'image_group':
                    $var = json_decode($item['var'], true);
                    break;
                case 'video':
                    $width = '100%';
                    $height = 400;
                    if (isset($params['width'])) {
                        $width = $params['width'];
                    }
                    if (isset($params['height'])) {
                        $height = $params['height'];
                    }
                    if (!empty(trim($item['var']))){
                        $var = '<embed align="middle" allowfullscreen="true" allowscriptaccess="always" class="cv-editor-video" height="' . $height . '" quality="high" src="'.config('cloud.video').trim($item['var']).'" type="application/x-shockwave-flash" width="' . $width . '"></embed>';
                    }
                    break;
                default:
                    $var = $item['var'];
            }
            return $var;
        }
        return '';
    }

    private function site($param)
    {
        $sitesFromCache = cache('sites');
        $siteId = SiteKit::currentSiteId();
        if (array_key_exists($siteId, $sitesFromCache)) {
            $site = $sitesFromCache[$siteId];
            if (isset($site[$param])) {
                if ($param == 'title') {
                    $site[$param] = $site[$param] . ' - P' . 'o' . 'w' . 'e' . 'r' . 'e' . 'd ' . 'B' . 'y ' . 'C' . 'o' . 'v' . 'e' . 'r' . 'P' . 'r' . 'i' . 's' . 'e';
                }elseif ($param=='company_info'){
                    $site[$param] = json_decode($site[$param]);
                }
                return $site[$param];
            }
        }
        return '';
    }

    public function getName()
    {
        return 'cover';
    }
}