<?php
/**
 * 菜单管理模块
 * Created by PhpStorm.
 * User: wxj
 * Date: 2019/10/30
 * Time: 14:02
 */

namespace JinDouYun\Model\System;

use Exception;
use Jindouyun\Cache\RoleAclCache;
use JinDouYun\Cache\SystemCache;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Factory;

use JinDouYun\Dao\System\DModule;

class MModule
{

    private $objDModule;
    private $objRoleAclCache;

    public function __construct()
    {
        $this->objDModule = new DModule('default');
        $this->objRoleAclCache = new RoleAclCache();
    }

    /**
     * 添加菜单管理
     * @param $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function addModule($params)
    {
        if (empty($params['extend'])) {
            if (self::checkAliasExists($params['alias'])) {
                return ResultWrapper::fail('别名已存在', ErrorCode::$dberror);
            }
        }
        $params['associate'] = json_encode($params['associate']);
        $params['associatePath'] = json_encode($params['associatePath']);

        $ModuleId = $this->objDModule->insert($params);

        if ($ModuleId === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        } else {
            if(!empty($params['extend'])){
                $this->objRoleAclCache->addAuthority($params['extend']);
            }
            $objSystemCache = new SystemCache();
            $objSystemCache->delUriRelName(strtolower($params['extend']));
            return ResultWrapper::success($ModuleId);
        }
    }

    /**
     * 获取指定菜单管理信息
     * @param $ModuleIds
     * @return ResultWrapper
     * @throws Exception
     */
    public function getModuleInfo($ModuleIds)
    {
        $dbResult = $this->objDModule->get_by('id', $ModuleIds);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        } else {
            $dbResult['associate'] = json_decode($dbResult['associate'], true);
            $dbResult['associatePath'] = json_decode($dbResult['associatePath'], true);
            return ResultWrapper::success($dbResult);
        }
    }


    /**
     * 编辑菜单管理
     * 事务修改联系人信息
     * @param int|array $params 修改菜单管理的数据
     *
     * @return ResultWrapper
     * @throws Exception
     */
    public function editModule($params)
    {
        if (empty($params['id'])) {
            return ResultWrapper::fail('没有指定要修改的菜单管理id', ErrorCode::$paramError);
        }
        $module = $this->objDModule->get(['id' => $params['id']]);
        if($module === false){
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        if(empty($module)){
            return ResultWrapper::fail('id不存在', ErrorCode::$dberror);
        }

        if (empty($params['extend'])) {
            if (self::checkAliasExists($params['alias'], $params['id'])) {
                return ResultWrapper::fail('别名已存在', ErrorCode::$dberror);
            }
        }

        $updateModuleId = $params['id'];
        unset($params['id']);
        $params['associate'] = json_encode($params['associate']);
        $params['associatePath'] = json_encode($params['associatePath']);
        $dbResult = $this->objDModule->update($params, $updateModuleId);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        } else {
            $this->objRoleAclCache->delAuthority($module['extend']);
            $result = $this->objRoleAclCache->addAuthority($params['extend']);
            if(!$result){
                return ResultWrapper::fail('缓存添加失败', ErrorCode::$paramError);
            }
            return ResultWrapper::success($dbResult);
        }
    }

    /**
     * 删除菜单管理
     *
     * @param array $delModuleIds 要删除的菜单管理id
     * @return ResultWrapper
     * @throws Exception
     */
    public function delModule($delModuleIds)
    {
        if (empty($delModuleIds)) {
            return ResultWrapper::fail('参数错误', ErrorCode::$paramError);
        }
        $module = $this->objDModule->get(['id' => $delModuleIds]);
        if($module === false){
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        if(empty($module)){
            return ResultWrapper::fail('id不存在', ErrorCode::$dberror);
        }

        $dbResult = $this->objDModule->get(['pid' => $delModuleIds, 'deleteStatus' => StatusCode::$standard]);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        if(!empty($dbResult)){
            return ResultWrapper::fail('请先删除所有下级', ErrorCode::$dberror);
        }

        $dbResult = $this->objDModule->update(['deleteStatus' => StatusCode::$delete], $delModuleIds);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        $this->objRoleAclCache->delAuthority($module['extend']);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 菜单管理启用和禁用
     * @param array $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function updateModuleStatus($params)
    {
        $module = $this->objDModule->get(['id' => $params['id']]);
        if($module === false){
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        if(empty($module)){
            return ResultWrapper::fail('id不存在', ErrorCode::$dberror);
        }
        if($params['enableStatus'] == StatusCode::$delete){
            $dbResult = $this->objDModule->select(['pid' => $params['id'], 'deleteStatus' => StatusCode::$standard, 'enableStatus' => StatusCode::$standard]);
            if($dbResult === false){
                return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
            }
            if(!empty($dbResult)){
                return ResultWrapper::fail('请先禁用所有下级', ErrorCode::$dberror);
            }

        }
        $dbResult = $this->objDModule->update(['enableStatus' => $params['enableStatus']], $params['id']);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        } else {
            if($params['enableStatus'] == StatusCode::$standard){
                $this->objRoleAclCache->addAuthority($module['extend']);
            }else{
                $this->objRoleAclCache->delAuthority($module['extend']);
            }
            $this->objRoleAclCache->delAuthority($params['id']);
            return ResultWrapper::success($dbResult);
        }
    }

    /**
     * 判断别名是否存在
     * @param $alias
     * @param null $id
     * @return bool
     */
    public function checkAliasExists($alias, $id = null)
    {
        $where = 'alias = "' . $alias . '"';
        if ($id) {
            $where .= ' AND id !=' . $id;
        }
        $where .= ' AND deleteStatus =' . StatusCode::$standard;
        $result = $this->objDModule->select($where);
        return !empty($result) ? true : false;
    }

    /**
     * 获取企业下的所有菜单管理数据
     *
     * @param $params
     * @return ResultWrapper
     */
    public function getAllModule($params)
    {
        $selectParams['deleteStatus'] = StatusCode::$standard;
        !empty($params['enableStatus']) && $selectParams['enableStatus'] = $params['enableStatus'];
        $dbResult = $this->objDModule->select($selectParams, '*', 'createTime asc');
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        $dbResult = self::arr2tree($dbResult);
        return ResultWrapper::success($dbResult);

    }

    public function getDataModule($where = [])
    {
        $dbResult = $this->objDModule->select($where);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 多维数组转树状结构
     *
     * @param $tree
     * @param int $rootId
     * @return array
     */
    public function arr2tree($tree, $rootId = 0)
    {
        $return = [];
        foreach ($tree as $leaf) {
            if ($leaf['pid'] == $rootId) {
                foreach ($tree as $subLeaf) {
                    if ($subLeaf['pid'] == $leaf['id']) {
                        $leaf['children'] = self::arr2tree($tree, $leaf['id']);
                        break;
                    }
                }
                $return[] = $leaf;
            }
        }
        return $return;
    }


    /**
     * Doc: (des="根据路径获取菜单路径名称")
     * User: XMing
     * Date: 2020/11/14
     * Time: 6:12 下午
     * @param string $uri
     * @return string
     */
    public function getModuleNameByUri(string $uri): string
    {
        $objSystemCache = new SystemCache();
        $moduleNames = $objSystemCache->getUriRelName($uri);
        if ($moduleNames != ''){
            return $moduleNames;
        }
        $module = $this->objDModule->get(['extend' => $uri], 'name,pid');
        if ($module === false){
            return '';
        }
        if ($module['pid'] == 0){
            $objSystemCache->setUriRelName($uri,$module['name']);
            return $module['name'];
        }
        $pid = $module['pid'];
        $moduleNames = '['.$module['name'].']';
        unset($module);
        while ($pid){
            $module = $this->objDModule->get(['id' => $pid],'pid,name');
            if ($module === false){
                return '';
            }
            $moduleNames = '['.$module['name'].']->'.$moduleNames;
            $pid = $module['pid'];
        }
        $objSystemCache->setUriRelName($uri,$moduleNames);
        return $moduleNames;
    }

    /**
     * 初始化缓存
     */
    public function initCache()
    {
        $data = $this->objDModule->select(['deleteStatus' => StatusCode::$standard, 'enableStatus' => StatusCode::$standard]);
        if($data === false){
            return ResultWrapper::fail($this->objDModule->error(), ErrorCode::$paramError);
        }
        foreach($data as $value){
            if(!empty($value['extend'])){
                $this->objRoleAclCache->addAuthority(strtolower($value['extend']));
            }
        }
        return ResultWrapper::success('初始化成功');
    }
}