<?php

namespace addons\webman\controller;

use addons\webman\Admin;
use addons\webman\model\AdminDepartment;
use addons\webman\model\AdminRole;
use ExAdmin\ui\component\common\Html;
use ExAdmin\ui\component\common\Icon;
use ExAdmin\ui\component\form\Form;
use ExAdmin\ui\component\grid\grid\Actions;
use ExAdmin\ui\component\grid\grid\Grid;
use ExAdmin\ui\component\grid\tag\Tag;


/**
 * 系统角色
 */
class RoleController
{
    public function __construct()
    {
        $this->model = plugin()->webman->config('database.role_model');
    }

    /**
     * 系统角色
     * @auth true
     * @return Grid
     */
    public function index(): Grid
    {
        return Grid::create(new $this->model(), function (Grid $grid) {
            $grid->title(admin_trans('auth.title'));
            $grid->autoHeight();
            $grid->column('name', admin_trans('auth.fields.name'));
            $grid->column('type', admin_trans('auth.fields.type'))
                ->display(function ($value) {
                    $tag = '';
                    switch ($value) {
                        case AdminDepartment::TYPE_DEPARTMENT:
                            $tag = Tag::create(admin_trans('auth.type.' . AdminDepartment::TYPE_DEPARTMENT))->color('#108ee9');
                            break;
                        case AdminDepartment::TYPE_CHANNEL:
                            $tag = Tag::create(admin_trans('auth.type.' . AdminDepartment::TYPE_CHANNEL))->color('#f50');
                            break;
                    }
                    return Html::create()->content([
                        $tag
                    ]);
                })->sortable();
            $grid->hideSelection();
            $grid->column('desc', admin_trans('auth.fields.desc'));
            $grid->column('data_type', admin_trans('auth.fields.data_type'))
                ->display(function ($value, AdminRole $data) {
                    $tag = '';
                    switch ($value) {
                        case AdminRole::DATA_TYPE_ALL:
                            $tag = Tag::create(admin_trans('auth.options.data_type.full_data_rights'))->color('#f50');
                            break;
                        case AdminRole::DATA_TYPE_CUSTOM:
                            $tag = Tag::create(admin_trans('auth.options.data_type.custom_data_permissions'))->color('#2db7f5');
                            break;
                        case AdminRole::DATA_TYPE_DEPARTMENT_BELOW:
                            $tag = Tag::create(admin_trans('auth.options.data_type.this_department_and_the_following_data_permissions'))->color('#87d068');
                            if ($data->type == AdminDepartment::TYPE_CHANNEL) {
                                $tag = Tag::create(admin_trans('auth.options.data_type.channel_and_the_following_data_permissions'))->color('#87d068');
                            }
                            break;
                        case AdminRole::DATA_TYPE_DEPARTMENT:
                            $tag = Tag::create(admin_trans('auth.options.data_type.data_permissions_for_this_department'))->color('#108ee9');
                            break;
                        case AdminRole::DATA_TYPE_SELF:
                            $tag = Tag::create(admin_trans('auth.options.data_type.personal_data_rights'))->color('#108ee9');
                            break;
                    }
                    return Html::create()->content([
                        $tag
                    ]);
                })->sortable();
            $grid->setForm()->modal($this->form());
            $grid->quickSearch();
            $grid->actions(function (Actions $actions, AdminRole $data) {
                $dropdown = $actions->dropdown();
                $dropdown->prepend(admin_trans('auth.auth_grant'), 'safety-certificate-filled')
                    ->modal($this->auth($data['id'], $data['type']));
                $dropdown->prepend(admin_trans('auth.menu_grant'), 'appstore-filled')
                    ->modal($this->menu($data['id'], $data['type']));
                $dropdown->prepend(admin_trans('auth.data_grant'), 'fas fa-database')
                    ->modal($this->data($data['id'], $data['type']));
                if ($data->id == AdminRole::ROLE_CHANNEL) {
                    $actions->hideDel();
                }
            });
        });

    }

    /**
     * 系统角色
     * @auth true
     * @return Form
     */
    public function form(): Form
    {
        return Form::create(new $this->model(), function (Form $form) {
            $form->title(admin_trans('auth.title'));
            $form->text('name', admin_trans('auth.fields.name'))->required();
            $form->textarea('desc', admin_trans('auth.fields.desc'))->rows(5)->required();
            $form->radio('type', admin_trans('auth.fields.type'))
                ->default(AdminDepartment::TYPE_DEPARTMENT)
                ->options([
                    AdminDepartment::TYPE_DEPARTMENT => admin_trans('auth.type.' . AdminDepartment::TYPE_DEPARTMENT),
                    AdminDepartment::TYPE_CHANNEL => admin_trans('auth.type.' . AdminDepartment::TYPE_CHANNEL),
                ])->disabled($form->isEdit());
            $form->number('sort', admin_trans('auth.fields.sort'))->default($this->model::max('sort') + 1);
            $form->saving(function (Form $form) {
                if (!$form->isEdit()) {
                    $type = $form->input('type');
                    switch ($type) {
                        case AdminDepartment::TYPE_DEPARTMENT:
                            $form->input('data_type', AdminRole::DATA_TYPE_ALL);
                            break;
                        case AdminDepartment::TYPE_CHANNEL:
                            $form->input('data_type', AdminRole::DATA_TYPE_DEPARTMENT_BELOW);
                            break;
                        default:
                            return message_error(admin_trans('auth.role_type_error'));
                    }
                }
            });
        });

    }

    /**
     * 数据权限
     * @auth true
     * @return Form
     */
    public function data($id, $type)
    {
        return Form::create(new $this->model(), function (Form $form) use ($type) {
            switch ($type) {
                case AdminDepartment::TYPE_DEPARTMENT:
                    $options = [
                        0 => admin_trans('auth.options.data_type.full_data_rights'),
                        1 => admin_trans('auth.options.data_type.custom_data_permissions'),
                        2 => admin_trans('auth.options.data_type.this_department_and_the_following_data_permissions'),
                        3 => admin_trans('auth.options.data_type.data_permissions_for_this_department'),
                        4 => admin_trans('auth.options.data_type.personal_data_rights'),

                    ];
                    break;
                case AdminDepartment::TYPE_CHANNEL:
                    $options = [
                        2 => admin_trans('auth.options.data_type.channel_and_the_following_data_permissions'),
                        3 => admin_trans('auth.options.data_type.data_permissions_for_this_department'),
                        4 => admin_trans('auth.options.data_type.personal_data_rights'),
                    ];
                    break;
                default:
                    $options = [];
            }
            $form->title(admin_trans('auth.title'));
            $form->desc('name', admin_trans('auth.fields.name'));
            $form->desc('desc', admin_trans('auth.fields.desc'));
            $form->select('data_type', admin_trans('auth.fields.data_type'))
                ->required()
                ->options($options)
                ->when(1, function (Form $form) {
                    $department = plugin()->webman->config('database.department_model');
                    $options = $department::where('status', 1)
                        ->where('type', AdminDepartment::TYPE_DEPARTMENT)
                        ->get()->toArray();
                    $tree = $form->tree('department')
                        ->showIcon()
                        ->content(Icon::create('FolderOutlined'), 'groupIcon')
                        ->multiple()
                        ->checkable()
                        ->bindAttr('checkStrictly', $form->getModel() . '.check_strictly')
                        ->options($options);
                    $form->popItem();
                    $form->switch('check_strictly', admin_trans('auth.fields.department'))
                        ->default(false)
                        ->checkedChildren(admin_trans('auth.father_son_linkage'))
                        ->unCheckedChildren(admin_trans('auth.father_son_linkage'))
                        ->checkedValue(false)
                        ->unCheckedValue(true)
                        ->getFormItem()->content($tree);

                });
        });
    }

    /**
     * 菜单权限
     * @auth true
     * @param $id
     * @param $type
     * @return Form
     */
    public function menu($id, $type): Form
    {
        $menuModel = plugin()->webman->config('database.menu_model');
        $tree = $menuModel::select('id', 'pid', 'name')->where('type', $type)->get()->toArray();
        $model = plugin()->webman->config('database.role_menu_model');
        $field = 'menu_id';
        $label = 'name';
        $nodeTypeList = [];
        foreach ($tree as $value) {
            if (!empty($value['group'])) {
                /** 全部菜单 */
                if ($value['group'] == 'all') {
                    $nodeTypeList[] = $value;
                }
                /** 渠道菜单,总站菜单 */
                if ($value['group'] == ($type == AdminDepartment::TYPE_CHANNEL ? 'channel' : 'department')) {
                    $nodeTypeList[] = $value;
                }
            } else {
                $nodeTypeList[] = $value;
            }
        }
        array_unshift($nodeTypeList, ['id' => 0, $label => admin_trans('auth.all'), 'pid' => -1]);
        $auths = $model::where('role_id', $id)->pluck($field);
        return Form::create(new $this->model(), function (Form $form) use ($id, $model, $nodeTypeList, $field, $auths, $label) {
            $form->tree('auth')
                ->options($nodeTypeList, $label)
                ->default($auths)
                ->checkable();
            $form->saving(function (Form $form) use ($id, $model, $field) {
                $auths = $form->input('auth');
                $form->removeInput('auth');
                $auths = array_filter($auths);
                $auths = array_map(function ($item) use ($id, $field) {
                    return ['role_id' => $id, $field => $item];
                }, $auths);
                $model::where('role_id', $id)->delete();
                if ($auths) {
                    $authsArr = array_chunk($auths, 10, true);
                    foreach ($authsArr as $value) {
                        $model::insert($value);
                    }
                }
            });
        });
    }

    /**
     * 功能权限
     * @auth true
     * @param $id
     * @param string $type
     * @return Form
     */
    public function auth($id, string $type = ''): Form
    {
        $tree = Admin::node()->all();
        $model = plugin()->webman->config('database.role_permission_model');
        $field = 'node_id';
        $label = 'title';
        $nodeTypeList = [];
        foreach ($tree as $value) {
            if (!empty($value['group'])) {
                /** 全部菜单 */
                if ($value['group'] == 'all') {
                    $nodeTypeList[] = $value;
                }
                /** 渠道菜单,总站菜单 */
                if ($value['group'] == ($type == AdminDepartment::TYPE_CHANNEL ? 'channel' : 'department')) {
                    $nodeTypeList[] = $value;
                }
            } else {
                $nodeTypeList[] = $value;
            }
        }
        array_unshift($nodeTypeList, ['id' => 0, $label => admin_trans('auth.all'), 'pid' => -1]);
        $auths = $model::where('role_id', $id)->pluck($field);
        return Form::create(new $this->model(), function (Form $form) use ($id, $model, $nodeTypeList, $field, $auths, $label) {
            $form->tree('auth')
                ->options($nodeTypeList, $label)
                ->default($auths)
                ->checkable();
            $form->saving(function (Form $form) use ($id, $model, $field) {
                $auths = $form->input('auth');
                $form->removeInput('auth');
                $auths = array_filter($auths);
                $auths = array_map(function ($item) use ($id, $field) {
                    return ['role_id' => $id, $field => $item];
                }, $auths);
                $model::where('role_id', $id)->delete();
                if ($auths) {
                    $authsArr = array_chunk($auths, 10, true);
                    foreach ($authsArr as $value) {
                        $model::insert($value);
                    }
                }
            });
        });
    }

    public function commonAuthForm($id, $model, $tree, $type, $field, $label): Form
    {
        $nodeTypeList = [];
        foreach ($tree as $value) {
            if (!empty($value['group'])) {
                /** 全部菜单 */
                if ($value['group'] == 'all') {
                    $nodeTypeList[] = $value;
                }
                /** 渠道菜单,总站菜单 */
                if ($value['group'] == ($type == AdminDepartment::TYPE_CHANNEL ? 'channel' : 'department')) {
                    $nodeTypeList[] = $value;
                }
            } else {
                $nodeTypeList[] = $value;
            }
        }
        array_unshift($nodeTypeList, ['id' => 0, $label => admin_trans('auth.all'), 'pid' => -1]);
        $auths = $model::where('role_id', $id)->pluck($field);
        return Form::create(new $this->model(), function (Form $form) use ($id, $model, $nodeTypeList, $field, $auths, $label) {
            $form->tree('auth')
                ->options($nodeTypeList, $label)
                ->default($auths)
                ->checkable();
            $form->saving(function (Form $form) use ($id, $model, $field) {
                $auths = $form->input('auth');
                $form->removeInput('auth');
                $auths = array_filter($auths);
                $auths = array_map(function ($item) use ($id, $field) {
                    return ['role_id' => $id, $field => $item];
                }, $auths);
                $model::where('role_id', $id)->delete();
                if ($auths) {
                    $authsArr = array_chunk($auths,10,true);
                    foreach ($authsArr as $value) {
                        $model::insert($value);
                    }
                }
            });
        });
    }
}
