<?php

namespace app\admin\controller\Menu;

use app\common\arw\adjfut\src\Traverse;
use app\BaseController;
use app\common\model\Menu\Menu as ModelMenu;
use app\common\model\Menu\MenuApi;
use app\common\model\Role\Role;
use app\common\model\Role\RoleMenu;
use app\Request;
use think\facade\Db;

class Menu extends BaseController
{

    /**
     * 获取菜单接口树
     *
     * @param Request $request
     * @return array
     * @date 2022-03-07
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function getMenuApiTree(Request $request)
    {
        $menu = ModelMenu::order([
            'menu_index',
            'menu_order' => 'desc',
        ])->field([
            'menu_guid',
            'menu_parent_guid',
            'menu_name',
            'menu_url',
        ])->select()->toArray();

        $menuApi = [];
        foreach (MenuApi::select() as $value) {
            if (!isset($menuApi[$value->menu_guid])) {
                $menuApi[$value->menu_guid] = [];
            }
            $menuApi[$value->menu_guid][] = $value->menu_api_url;
        }

        $Traverse = new Traverse('menu_guid', 'menu_parent_guid');
        $menuTree = $Traverse->tree($menu, '0', function ($v) use ($menuApi) {
            return [
                'menu_api_url' => isset($menuApi[$v['menu_guid']]) ? $menuApi[$v['menu_guid']] : [],
                'menu_name' => $v['menu_name'],
                'menu_guid' => $v['menu_guid'],
                'menu_parent_guid' => $v['menu_parent_guid'],
                'menu_url' => $v['menu_url'],
            ];
        }, function ($v) {
            $v['hasChildren'] = isset($value['children']) && count($value['children']);
            return $v;
        });

        return [
            'code' => 0,
            'msg' => 'ok',
            'data' => $menuTree,
        ];
    }

    /**
     * 添加菜单接口
     *
     * @param Request $request
     * @return array
     * @date 2022-03-08
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function addMenuApi(Request $request)
    {
        Db::startTrans();
        try {
            $params = $request->param();
            $this->validate($params, [
                'menu_guid' => 'require',
                'menu_api_url' => 'require'
            ]);
            foreach (explode(',', $params['menu_api_url']) as $menu_api_url) {
                MenuApi::create([
                    'menu_guid' => $params['menu_guid'],
                    'menu_api_url' => $menu_api_url,
                ]);
            }
            Db::commit();
            return [
                'code' => 0,
                'msg' => '添加成功',
            ];
        } catch (\Throwable $th) {
            Db::rollback();
            throw $th;
        }
    }

    /**
     * 删除菜单接口
     *
     * @param Request $request
     * @return array
     * @date 2022-03-08
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function deleteMenuApi(Request $request)
    {
        $params = $request->param();
        $this->validate($params, [
            'menu_api_guid' => 'require'
        ]);
        MenuApi::where([
            'menu_api_guid' => explode(',', $params['menu_api_guid'])
        ])->select()->delete();
        return [
            'code' => 0,
            'msg' => "删除成功"
        ];
    }

    /**
     * 获取菜单接口列表
     *
     * @param Request $request
     * @return array
     * @date 2022-03-07
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function getMenuApiList(Request $request)
    {
        $params = $request->param();
        $this->validate($params, [
            'menu_guid' => 'require'
        ]);
        $query = ModelMenu::find($params['menu_guid'])->apis()->append([
            'menu_api_status_text'
        ]);
        $data = self::pageWrapper($query)->select();
        $count = $query->count();
        return [
            'code' => 0,
            'msg' => 'ok',
            'data' => $data,
            'count' => $count
        ];
    }

    /**
     * 获取菜单树
     *
     * @param Request $request
     * @return array
     * @date 2022-03-05
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function getMenuTree(Request $request)
    {
        $menu = ModelMenu::order([
            'menu_index',
            'menu_order' => 'desc',
        ])->field([
            'menu_parent_guid',
            'menu_name',
            'menu_url',
            'menu_index',
            'menu_order',
            'menu_status',
            'menu_show',
            'menu_guid',
        ])->select()->toArray();

        array_unshift($menu, [
            'menu_guid' => '0',
            'menu_parent_guid' => '-1',
            'menu_name' => '系统菜单',
            'menu_index' => 0,
            'menu_order' => 0,
            'menu_status' => 0,
            'menu_show' => 0,
            'menu_url' => '',
        ]);

        $Traverse = new Traverse('menu_guid', 'menu_parent_guid');
        $menuTree = $Traverse->tree($menu, '-1', function ($v) {
            return [
                'label' => $v['menu_name'],
                'id' => $v['menu_guid'],
                'parent_id' => $v['menu_parent_guid'],
                'index' => $v['menu_index'],
                'order' => $v['menu_order'],
                'status' => $v['menu_status'],
                'show' => $v['menu_show'],
                'url' => $v['menu_url'],
            ];
        });

        return [
            'code' => 0,
            'msg' => 'ok',
            'data' => $menuTree
        ];
    }

    /**
     * 获取角色菜单
     *
     * @param Request $request
     * @return array
     * @date 2022-03-09
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function getRoleMenu(Request $request)
    {
        $params =  $request->param();
        $this->validate($params, [
            'role_guid' => 'require'
        ]);
        $menus = Role::getByRoleGuid($params['role_guid'])->menus;
        $menu_guids = [];
        $menu_parent_guids = [];
        foreach ($menus as $menu) {
            if (!in_array($menu->menu_guid, $menu_guids)) {
                $menu_guids[] = $menu->menu_guid;
            }
            if (!in_array($menu->menu_parent_guid, $menu_parent_guids)) {
                $menu_parent_guids[] = $menu->menu_parent_guid;
            }
        }
        // 去除父id 存在父id会全选子节点
        $temp = [];
        foreach ($menu_guids as $menu_guid) {
            if (!in_array($menu_guid, $menu_parent_guids)) {
                $temp[] = $menu_guid;
            }
        }
        return [
            'code' => 0,
            'data' => $temp,
            'msg' => 'ok'
        ];
    }

    /**
     * 绑定角色菜单
     *
     * @param Request $request
     * @return array
     * @date 2022-03-09
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function bindRoleMenu(Request $request)
    {
        $params = $request->param();
        $this->validate($params, [
            'role_guid' => 'require',
            'menu_guid' => 'require'
        ]);
        $menus = array_map(function ($v) {
            return ModelMenu::find($v);
        }, explode(',', $params['menu_guid']));
        RoleMenu::rebindRoleMenu(
            [
                Role::getByRoleGuid($params['role_guid']),
            ],
            array_filter($menus)
        );
        return [
            'code' => 0,
            'msg' => '绑定成功'
        ];
    }

    /**
     * 添加菜单
     *
     * @param Request $request
     * @return array
     * @date 2022-03-05
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function addMenu(Request $request)
    {
        $params = $request->param();
        $this->validate($params, [
            'menu_name' => 'require',
            'menu_index' => 'require',
            'menu_order' => 'require',
            'menu_show' => 'require',
            'menu_parent_guid' => 'require',
        ]);
        if (isset($params['menu_guid'])) {
            unset($params['menu_guid']);
        }
        ModelMenu::create($params);
        return [
            'code' => 0,
            'msg' => '添加成功'
        ];
    }

    /**
     * 更新菜单
     *
     * @param Request $request
     * @return array
     * @date 2022-03-05
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function updateMenu(Request $request)
    {
        $params = $request->param();
        $this->validate($params, [
            'menu_guid' => 'require'
        ]);
        ModelMenu::withoutGlobalScope(['status'])->update($params, [
            'menu_guid' => $params['menu_guid']
        ]);
        return [
            'code' => 0,
            'msg' => '更新成功'
        ];
    }

    /**
     * 删除菜单
     *
     * @param Request $request
     * @return array
     * @date 2022-03-05
     * @example
     * @author admin
     * @since 1.0.0
     */
    public function deleteMenu(Request $request)
    {
        $params = $request->param();
        $this->validate($params, [
            'menu_guid' => 'require'
        ]);
        ModelMenu::where([
            'menu_guid' => explode(',', $params['menu_guid'])
        ])->select()->delete();
        return [
            'code' => 0,
            'msg' => '删除成功'
        ];
    }
}
