<?php
/**
 * Created by PhpStorm.
 * User: qiuzijian
 * Date: 2021-04-17
 * Time: 17:16
 */

namespace Modules\Admin\Traits;

use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

trait ClassifyMethod
{
    /**
     * 模型对象
     * @var
     */
    protected $classify;

    /**
     * 缓存名
     * @var string
     */
    public $cacheTitle = 'Classify';

    /**
     * 排序方式
     * @var string
     */
    public $sort = 'desc';

    /**
     * 删除
     * @param $classifyInfo
     * @return mixed
     */
    public function add($classifyInfo)
    {
        return $this->addOrEdit($classifyInfo);
    }

    /**
     * 添加
     * @param $classifyInfo
     * @return bool
     */
    public function edit($classifyInfo)
    {
        if (!isset($classifyInfo['id'])) {
            return false;
        }
        return $this->addOrEdit($classifyInfo);
    }

    /**
     * 递归删除
     * @param $classifyId
     * @return bool
     */
    public function del($classifyId)
    {
        if (empty($classifyId)) {
            return false;
        }
        $classify = $this->classify->find($classifyId);
//        $subClassifys = $this->classify->where('parent_id', $classifyId)->get()->toArray();
//        if (count($subClassifys) > 0) {  // 如果有子菜单将子菜单删除
//            foreach ($subClassifys as $subClassify) {
//                self::del($subClassify['id']);
//            }
//        }
        if ($classify) {
            $this->classify->where('degree', 'like', $classify->degree . '|%')->delete();
            $classify->delete();
        }
        $this->sortClassifyAndddCache(1);
        $this->sortClassifyAndddCache();
        return true;
    }

    /**
     * 获取单个信息
     * @param $classifyId
     * @return false
     */
    public function getOneInfo($classifyId)
    {
        if (!$classifyId) {
            return false;
        }
        return $this->classify->find($classifyId);
    }

    /**
     * 获取所有
     * @return mixed
     */
    public function getAll($show = '')
    {
        if (!empty($show)) {
            return $this->classify->where('show', $show)->all();
        }
        return $this->classify->all();
    }

    /**
     * 获取层级列表
     * @param string $show
     * @param string $category
     * @return array|mixed|string
     */
    public function getTierList($show = '', $degree = '')
    {
        // 判断并获取缓存
        if (!empty($show)) {
            if (Cache::has($this->cacheTitle . 'ShowList')) {
                $classifyList = Cache::get($this->cacheTitle . 'ShowList');
            } else {
                $classifyList = $this->sortClassifyAndddCache(1);
            }
        } else {
            if (Cache::has($this->cacheTitle . 'List')) {
                $classifyList = Cache::get($this->cacheTitle . 'List');
            } else {
                $classifyList = $this->sortClassifyAndddCache();
            }
        }

        $classifyList = empty($classifyList) ? [] : $classifyList;
        if (empty($degree)) {
            return $classifyList;
        }

        return Arr::get($classifyList, $degree);

    }


    /**
     * 递归岗位数据
     * @param     $classify
     * @param int $pid
     * @return array|string
     */
    public function sortClassify($classify, $pid = '0')
    {
        $arr = [];
        if (empty($classify)) {
            return '';
        }
        $num = 0;
        foreach ($classify as $key => $value) {
            if ($value['parent_id'] == $pid) {
                $arr[$num]          = $value;
                $arr[$num]['child'] = self::sortClassify($classify, $value['id']);
                if (count($arr[$num]['child']) == 0) {
                    unset($arr[$num]['child']);
                }
                $num++;
            }
        }
        return $arr;
    }

    /**
     * 排序子岗位并缓存
     * ---------------------------------
     * array_column($array,$name)
     * $array => 要查询的数组
     * $name  => 在数组中要返回的字段值
     *----------------------------------
     * array_multisort($array1,$rule,$array2)
     * $array1 => 规定数组(规定以这个数组来排序)
     * $rule   => 规定排列顺序。
     * 可能的值：
     *   SORT_ASC - 默认。按升序排列 (A-Z)。
     *   SORT_DESC - 按降序排列 (Z-A)。
     * $array2 => 要规定的数组。(要排序的数组)
     */
    public function sortClassifyAndddCache($show = '')
    {
        $classify = $this->classify;
        if (!empty($show)) {
            $classify = $classify->where('show', $show);
        }
        $classify = $classify->orderBy('sort', $this->sort)->get()->toArray();
        if ($classify) {
            $classifyList = $this->sortClassify($classify);
            foreach ($classifyList as $key => $value) {
                if (isset($value['child'])) {
                    $sort = array_column($value['child'], 'sort');
                    if ($this->sort == 'desc') {
                        array_multisort($sort, SORT_ASC, $value['child']);
                    } else {
                        array_multisort($sort, SORT_DESC, $value['child']);
                    }
                }
            }
            if (!empty($show)) {
                Cache::forever($this->cacheTitle . 'ShowList', $classifyList);
            } else {
                Cache::forever($this->cacheTitle . 'List', $classifyList);
            }
            return $classifyList;
        }
        Cache::forget($this->cacheTitle . 'List');
        Cache::forget($this->cacheTitle . 'ShowList');
        return '';
    }

    protected function addOrEdit($classifyInfo)
    {
        // 判断层级
        $classifyInfo['parent_id'] = $classifyInfo['parent_id'] ?? 0;
        if ($classifyInfo['parent_id'] == 0) {
            $classifyInfo['tier'] = 1;
            $degree               = '';
        } else {
            $classifyParent       = $this->classify->find($classifyInfo['parent_id']);
            $classifyInfo['tier'] = $classifyParent->tier + 1;
            $degree               = $classifyParent->degree . '|';
        }
        // 将标题转化成拼音作为标记
        if (empty($classifyInfo['slug'])) {
            $classifyInfo['slug'] = implode(array_map(function ($v) {
                return ucfirst($v);
            }, pinyin($classifyInfo['title'])));
        }

        if (isset($classifyInfo['id'])) {
            $curClassifyInfo = $this->classify->find($classifyInfo['id']);
        }

        $classify         = $this->classify->updateOrCreate(['id' => $classifyInfo['id'] ?? ''], $classifyInfo);
        $classify->degree = $degree . $classify->id;
        $classify->save();

        // 更新子集
        if (isset($classifyInfo['id']) && $curClassifyInfo['degree'] != $classify['degree']) {  // 如果改变父级，联动改变其下属所有子集
            $diffTier       = $curClassifyInfo['tier'] - $classifyInfo['tier'];
            $childClassifys = $this->classify->where('degree', 'like', $curClassifyInfo['degree'] . '|%')->get();
            foreach ($childClassifys as $childClassify) {
                $degree            = str_replace($curClassifyInfo['degree'] . '|', $classify['degree'] . '|', $childClassify['degree']);
                $_classify         = $this->classify->where('id', $childClassify['id'])->first();
                $_classify->degree = $degree;
                $_classify->tier   = $_classify->tier - $diffTier;
                $_classify->save();
            }
        }

        $this->sortClassifyAndddCache(1);
        $this->sortClassifyAndddCache();

        return $classify;
    }
}
