<?php
namespace App\Traits;

use App\Models\Tag;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

trait ModelTrait
{

    /**
     * 限制查询当前语言版本。
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLang($query)
    {
        return $query->where('lang', config('lang'));
    }

    /**
     * 限制查询内容状态
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeFlag($query, $flag = 1)
    {
        return $query->where('flag', $flag);
    }

    /**
     * 添加别名
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function attachSlug($model, $slug, $pk = 'id')
    {
        if (!request('slug')) {
            $slug   = app('pinyin')->sentence($slug);
        }

        if (!request('slug') && !in_array(config('setting.lang'), ['en', 'cn', 'hk'])) {
            $slug  = $model->$pk;
        }

        $slug        = request('slug') ? str_slug(request('slug')) : str_slug($slug);
        $count       = self::where('slug', $slug)->where($pk, '<>', $model->$pk)->count();
        $model->slug = $count > 0 ? $slug . '-' . $model->$pk : $slug;

        return $model->save();
    }

    /**
     * 获取对应token
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
     public static function token($platform = "facebook", $type = "access_token")
     {
         $data  = self::where('flag', 1)->get(['platform', 'access_token', 'refresh_token'])->toArray();
         $token = '';
         foreach ($data as $key => $value) {
             if ($value['platform'] == $platform) {
                $token = $value[$type];
             }
         }

         return $token;
     }

    /**
     * 统计tag使用次数
     *
     * @return \Illuminate\Database\Connection
     */
     public static function tagCount()
     {
        $taggableType = get_called_class();
        $tags   = Tag::lists('name', 'tag_id');
        $tagIds = $tags->keys();

        $taggables = DB::table('taggable_taggables')
            ->selectRaw('count(*) as aggregate, tag_id, taggable_type')
            ->where('taggable_type', $taggableType)
            ->whereIn('tag_id', $tagIds)
            ->groupBy('tag_id')
            ->get();

        $taggables = collect($taggables)->pluck('aggregate', 'tag_id')->toArray();
        $tagsOld   = $tags;
        $tags = $tags->map(function ($item, $key) use($taggables) {
            $count = $taggables[$key] ?? 0;
            return $item ."(${count})";
        });
        
        return array_combine($tagsOld->toArray(), $tags->toArray());
     }

    /**
     * 添加 description
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function attachDescription(array $data, int $id, $field = 'product_id', $isAdd = false)
    {
        foreach ($data as $key => $value) {
            $value['lang']  = $key;
            $value[$field]  = $id;
            if (isset($value['name'])) $value['name']  = trim($value['name']);
            if ($isAdd) {
                self::create($value);
            } else {
                if ($exist = self::where($field, $id)->where('lang', $key)->first()) {
                    $exist->update($value);
                } else {
                    self::create($value);
                }
            }
        }
    }

    /**
     * 判断tags有哪些词被选中
     *
     * @param string | array $tagarr
     * @param array $tags            
     * @return array
     */
    public static function isSelect($tagarr, $tags)
    {
        if (! is_array($tagarr)) {
            $tagarr = (array) $tagarr;
        }
        
        foreach ($tags as &$tag) {
            if (in_array($tag['title'], $tagarr)) {
                $tag['select'] = 1;
            } else {
                $tag['select'] = 0;
            }
        }
        return $tags;
    }

    /**
     *
     * @param array $where
     * @param int $page
     * @return Illuminate\Pagination\LengthAwarePaginator
     */
    public static function paginateList($where = [], $page = 20)
    {
        $model = static::with(['cates', 'description']);

        // 模型名称
        if (isset($where['title']) && $where['title']) {
            $description = get_called_class() . 'Description';
            $ids   = $description::where('title', 'like', "%{$where['title']}%")->where('lang', config('setting.lang'))->get()->pluck($where['field'])->toArray();
            $model = $model->whereIn('id', $ids);
        }

        // 模型分类
        if (isset($where['pid']) && $where['pid']) {
            $cateModel = get_called_class() == 'App\Models\Cases' ? 'App\Models\CaseCate' : get_called_class() . 'Cate';
            $cate = $cateModel::find($where['pid']);
            $ids = $cate->getDescendantsAndSelf(['id'])->pluck('id')->toArray();
            $model = $model->whereIn('pid', $ids); 
        }

        //模型属性
        if (isset($where['attribute']) && $where['attribute']) {
            $model = $model->where($where['attribute'], 1);
        }

        //状态
        if (isset($where['flag']) && $where['flag']) {
            $model = $model->where('flag', ($where['flag'] - 1));
        }

        //是否采集
        if (isset($where['is_collect']) && $where['is_collect']) {
            $model = $model->where('is_collect', ($where['is_collect'] - 1));
        }

        if (isset($where['perPage']) && $where['perPage']) {
            $page = $where['perPage'];
        }
        
        return $model->orderBy('orders', 'DESC')->latest()->paginate($page);
    }

    //判断分类是否可以删除
    public static function canDelete($ids, $parentId = '', $isContent = true) 
    {
        $ids    = array_str($ids);
        foreach ($ids as $val) {
            if ($isContent && self::find($val)->pages->count() > 0 ) {
                return ['status' => 'error', 'message' => '所删分类中含有内容，请先转移或删除内容！'];
            }
            if (self::where('parent_id', $val)->first()) {
                return ['status' => 'error', 'message' => '所删分类中含有子类，请先删除子类！'];
            }
        }

        $res    = self::whereIn('id', $ids)->delete();

        if ($res) {
            if ($parentId) {
                $descriptionModel = get_called_class() . 'Description';
                $descriptionModel::whereIn($parentId, $ids)->delete();
            }
            \App\Models\SystemLog::set("删除". config('system.log_models')[get_called_class()] ."成功[id=". implode(',', $ids) ."]");
            return ['status' => 'sucess', 'message' => '分类删除成功！'];
        }

        return ['status' => 'error', 'message' => '分类删除失败！'];
    }

    /**
     * @param array $data                      
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function createAll($data)
    {
        array_map(function($value) { static::create($value); }, $data);
    }


    /**
     * @param String $ids                      
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function deletes($ids, $parentId = '')
    {
        $ids = array_str($ids);

        $descriptionModel = get_called_class() . 'Description';

        foreach ($ids as $id) {
            if (get_called_class() == "App\Models\Product") {
                $content = [];
                $data = $descriptionModel::where('lang', config('setting.lang'))->where('product_id', $id)->first();
                if ($data) {
                    $content = [
                        'title' => $data->title,
                        'content' => $data->content
                    ];
                }
                \App\Models\SystemLog::set("删除". config('system.log_models')[get_called_class()] ."成功[id=". $id ."]", json_encode($content));
            } else {
                \App\Models\SystemLog::set("删除". config('system.log_models')[get_called_class()] ."成功[id=". $id ."]");
            }
        }

        if ($parentId) {
            $descriptionModel::whereIn($parentId, $ids)->delete();
        }
        
        return self::whereIn('id', $ids)->delete();
    }

    /**
     * 限制会员查询
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeMemberId($query)
    {
        return $query->where('member_id', Auth::member()->get()->id);
    }
}