<?php namespace Phpcmf\Controllers\Admin;


class Auth extends \Phpcmf\Common
{

    // 用户权限开关项
    protected $member_check_fields = [
        'avatar' => '强制上传头像',
        'complete' => '强制完善资料',
        'mobile' => '强制手机认证',
        'email' => '强制邮箱认证',
        'downfile' => '附件下载权限',
        'uploadfile' => '附件上传权限',
    ];

    // 用户权限数值项
    protected $member_number_fields = [
        'login' => [
            'name' => '每日登录奖励',
            'items' => [
                'login_score' => ['app' => 'scorelog', 'unit' => 'score'],
                'login_exp' => ['app' => 'explog', 'unit' => 'exp'],
            ],
        ],
        'avatar_award' => [
            'name' => '头像认证奖励',
            'items' => [
                'avatar_score' => ['app' => 'scorelog', 'unit' => 'score'],
                'avatar_exp' => ['app' => 'explog', 'unit' => 'exp'],
            ],
        ],
    ];

    public function index() {

        // 用户组列
        $group = [
            0 => [
                'id' => 0,
                'name' => dr_lang('游客'),
                'use' => 1,
            ]
        ];
        foreach ($this->member_cache['group'] as $t) {
            $group[$t['id']] = [
                'id' => $t['id'],
                'name' => dr_lang($t['name']),
                'use' => 1,
            ];
        }

        // 用户组等级列
        $level = [
            0 => [
                'id' => 0,
                'name' => dr_lang('游客'),
                'group_name' => '',
                'level_name' => dr_lang('游客'),
                'use' => 1,
            ]
        ];
        foreach ($this->member_cache['group'] as $t) {
            $gname = dr_lang($t['name']);
            $level[$t['id']] = [
                'id' => $t['id'],
                'name' => $gname,
                'group_name' => '',
                'level_name' => $gname,
                'use' => 1,
            ];
            if ($t['level']) {
                foreach ($t['level'] as $lv) {
                    $lname = dr_lang($lv['name']);
                    $level[$t['id'].'-'.$lv['id']] = [
                        'id' => $t['id'].'-'.$lv['id'],
                        'name' => $gname.' / '.$lname,
                        'group_name' => $gname,
                        'level_name' => $lname,
                        'use' => 1,
                    ];
                    $level[$t['id']]['use'] = 0;
                }
            }
        }

        $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth_type')->get()->getRowArray();
        $auth_type = intval($v['value']);

        // 当前模式对应的列
        if ($auth_type == 1) {
            $columns = $group;
        } elseif ($auth_type == 2) {
            $columns = [];
            foreach ($level as $i => $t) {
                if ($t['use']) {
                    $columns[$i] = $t;
                }
            }
        } else {
            $columns = [
                'public' => [
                    'id' => 'public',
                    'name' => dr_lang('全局'),
                    'use' => 1,
                ]
            ];
        }

        // 读取权限
        $row = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray();
        $value = $row ? dr_string2array($row['value']) : [];
        if (!is_array($value)) {
            $value = [];
        }
        $auth_data = isset($value[SITE_ID]) && is_array($value[SITE_ID]) ? $value[SITE_ID] : [];

        if (IS_AJAX_POST) {

            $post = \Phpcmf\Service::L('input')->post('data');
            if (!is_array($post)) {
                $post = [];
            }

            foreach ($columns as $aid => $col) {
                $key = (string)$aid;
                $old = [];
                if (isset($auth_data[$aid]) && is_array($auth_data[$aid])) {
                    $old = $auth_data[$aid];
                } elseif (isset($auth_data[$key]) && is_array($auth_data[$key])) {
                    $old = $auth_data[$key];
                }

                // 仅读取当前列提交值，且只白名单写入，避免 POST 注入多余字段
                $post_member = [];
                if (isset($post[$aid]['member']) && is_array($post[$aid]['member'])) {
                    $post_member = $post[$aid]['member'];
                } elseif (isset($post[$key]['member']) && is_array($post[$key]['member'])) {
                    $post_member = $post[$key]['member'];
                }

                $member = [];
                foreach ($this->member_check_fields as $field => $name) {
                    $member[$field] = empty($post_member[$field]) ? 0 : 1;
                }
                foreach ($this->member_number_fields as $group_item) {
                    foreach ($group_item['items'] as $field => $cfg) {
                        $member[$field] = isset($post_member[$field]) ? intval($post_member[$field]) : 0;
                    }
                }

                $old['member'] = $member;
                // 应用插件 / 内容权限仍保留，此处不覆盖
                $auth_data[$aid] = $old;
            }

            $value[SITE_ID] = $auth_data;
            \Phpcmf\Service::M()->db->table('member_setting')->replace([
                'name' => 'auth2',
                'value' => dr_array2string($value)
            ]);
            \Phpcmf\Service::M('cache')->sync_cache('member');
            $this->_json(1, dr_lang('操作成功'));
        }

        $diy = $this->_get_diy();
        $col_count = dr_count($columns);
        $is_single = $col_count <= 1;

        // 取某列已存 member 配置
        $get_member = function ($aid) use ($auth_data) {
            $key = (string)$aid;
            if (isset($auth_data[$aid]['member']) && is_array($auth_data[$aid]['member'])) {
                return $auth_data[$aid]['member'];
            }
            if (isset($auth_data[$key]['member']) && is_array($auth_data[$key]['member'])) {
                return $auth_data[$key]['member'];
            }
            return [];
        };

        $form_html = '';
        $thead_html = '';
        $tbody_html = '';

        if ($is_single) {
            // 全局模式：标准表单排版
            $aid = 'public';
            foreach ($columns as $k => $col) {
                $aid = (string)$k;
                break;
            }
            $member = $get_member($aid);
            $aid_attr = htmlspecialchars($aid);

            foreach ($this->member_check_fields as $field => $name) {
                $checked = !empty($member[$field]) ? ' checked' : '';
                $form_html .= '<div class="form-group">'
                    .'<label class="col-md-2 control-label">'.dr_lang($name).'</label>'
                    .'<div class="col-md-9">'
                    .'<input type="checkbox" name="data['.$aid_attr.'][member]['.$field.']" value="1"'.$checked
                    .' data-on-text="'.dr_lang('是').'" data-off-text="'.dr_lang('否').'"'
                    .' data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">'
                    .'</div></div>';
            }

            foreach ($this->member_number_fields as $item) {
                $form_html .= '<div class="form-group">'
                    .'<label class="col-md-2 control-label">'.dr_lang($item['name']).'</label>'
                    .'<div class="col-md-9">';
                foreach ($item['items'] as $field => $cfg) {
                    $val = intval(isset($member[$field]) ? $member[$field] : 0);
                    $readonly = (($cfg['app'] == 'scorelog' && !dr_is_app('scorelog'))
                        || ($cfg['app'] == 'explog' && !dr_is_app('explog'))) ? ' readonly' : '';
                    $unit = $cfg['unit'] == 'score' ? SITE_SCORE : SITE_EXPERIENCE;
                    $form_html .= '<label style="margin-right:10px;">'
                        .'<div class="input-group" style="width:200px;">'
                        .'<input type="text" class="form-control" name="data['.$aid_attr.'][member]['.$field.']" value="'.$val.'"'.$readonly.'>'
                        .'<span class="input-group-btn"><button class="btn default" type="button">+'.htmlspecialchars((string)$unit).'</button></span>'
                        .'</div></label>';
                }
                $form_html .= '</div></div>';
            }

            if (!empty($diy['app'])) {
                $url = dr_url('member/auth/add', ['aid' => $aid, 'page' => 'app']);
                $form_html .= '<div class="form-group">'
                    .'<label class="col-md-2 control-label">'.dr_lang('应用插件权限').'</label>'
                    .'<div class="col-md-9">'
                    .'<a href="'.$url.'" class="btn blue btn-sm"><i class="fa fa-puzzle-piece"></i> '.dr_lang('设置').'</a>'
                    .'</div></div>';
            }
        } else {
            // 多列矩阵
            $thead_html = '<th class="fc-auth-name">'.dr_lang('权限项').'</th>';
            foreach ($columns as $aid => $col) {
                $key = (string)$aid;
                if ($key === '0') {
                    $title = '<span class="font-red">'.htmlspecialchars((string)$col['name']).'</span>';
                } elseif (!empty($col['group_name'])) {
                    $title = '<span class="fc-auth-gname">'.htmlspecialchars((string)$col['group_name']).'</span>'
                        .'<span class="fc-auth-lname">'.htmlspecialchars((string)$col['level_name']).'</span>';
                } else {
                    $title = htmlspecialchars((string)$col['name']);
                }
                $thead_html .= '<th class="fc-auth-col">'.$title.'</th>';
            }

            foreach ($this->member_check_fields as $field => $name) {
                $tbody_html .= '<tr><td class="fc-auth-name">'.dr_lang($name).'</td>';
                foreach ($columns as $aid => $col) {
                    $key = (string)$aid;
                    $member = $get_member($aid);
                    $checked = !empty($member[$field]) ? ' checked' : '';
                    $tbody_html .= '<td class="fc-auth-col">'
                        .'<input type="checkbox" class="fc-auth-check" name="data['.htmlspecialchars($key).'][member]['.$field.']" value="1"'.$checked.' />'
                        .'</td>';
                }
                $tbody_html .= '</tr>';
            }

            foreach ($this->member_number_fields as $item) {
                $tbody_html .= '<tr><td class="fc-auth-name">'.dr_lang($item['name']).'</td>';
                foreach ($columns as $aid => $col) {
                    $key = (string)$aid;
                    $member = $get_member($aid);
                    $tbody_html .= '<td class="fc-auth-col fc-auth-num-cell">';
                    foreach ($item['items'] as $field => $cfg) {
                        $val = intval(isset($member[$field]) ? $member[$field] : 0);
                        $readonly = (($cfg['app'] == 'scorelog' && !dr_is_app('scorelog'))
                            || ($cfg['app'] == 'explog' && !dr_is_app('explog'))) ? ' readonly' : '';
                        $unit = $cfg['unit'] == 'score' ? SITE_SCORE : SITE_EXPERIENCE;
                        $tbody_html .= '<div class="input-group input-group-sm fc-auth-num">'
                            .'<input type="text" class="form-control" name="data['
                            .htmlspecialchars($key).'][member]['.$field.']" value="'.$val.'"'.$readonly.' />'
                            .'<span class="input-group-addon">+'.htmlspecialchars((string)$unit).'</span>'
                            .'</div>';
                    }
                    $tbody_html .= '</td>';
                }
                $tbody_html .= '</tr>';
            }

            if (!empty($diy['app'])) {
                $tbody_html .= '<tr><td class="fc-auth-name">'.dr_lang('应用插件权限').'</td>';
                foreach ($columns as $aid => $col) {
                    $key = (string)$aid;
                    $url = dr_url('member/auth/add', ['aid' => $key, 'page' => 'app']);
                    $tbody_html .= '<td class="fc-auth-col">'
                        .'<a href="'.$url.'" class="btn blue btn-xs"><i class="fa fa-puzzle-piece"></i> '.dr_lang('设置').'</a>'
                        .'</td>';
                }
                $tbody_html .= '</tr>';
            }
        }

        \Phpcmf\Service::V()->assign([
            'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
                [
                    '用户权限' => ['member/auth/index', 'fa fa-cog'],
                    'help' => [801],
                ]
            ),
            'auth_type' => $auth_type,
            'is_single' => $is_single,
            'is_cms' => (defined('IS_USE_CMS') && IS_USE_CMS) ? 1 : 0,
            'cms_auth_url' => (defined('IS_USE_CMS') && IS_USE_CMS) ? dr_url('cms/auth/index') : '',
            'form_html' => $form_html,
            'thead_html' => $thead_html,
            'tbody_html' => $tbody_html,
        ]);
        \Phpcmf\Service::V()->display('member_auth.html');
    }

    // 存储模式值
    public function save_edit() {

        $value = intval(\Phpcmf\Service::L('input')->get('value'));
        if (!$value) {
            $msg = dr_lang('已切换至按全局配置模式');
        } elseif ($value == 1) {
            $msg = dr_lang('已切换至按用户组配置模式');
        } elseif ($value == 2) {
            $msg = dr_lang('已切换至按用户组等级配置模式');
        } else {
            $this->_json(0, dr_lang('未知模式'));
        }

        \Phpcmf\Service::M()->db->table('member_setting')->replace([
            'name' => 'auth_type',
            'value' => $value
        ]);
        \Phpcmf\Service::M('cache')->sync_cache('member');

        $this->_json(1, $msg);
    }

    // 初始化组权限（仅清空用户相关配置，保留内容权限）
    public function init_edit() {

        $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray();
        $aid = \Phpcmf\Service::L('input')->get('aid');
        if ($aid === null || $aid === false || $aid === '') {
            $this->_json(0, dr_lang('参数错误'));
        }
        // 允许 public / 数字组ID / 组-等级
        if ($aid !== 'public' && $aid !== '0' && $aid !== 0
            && !preg_match('/^\d+(-\d+)?$/', (string)$aid)) {
            $this->_json(0, dr_lang('参数错误'));
        }
        $value = $v ? dr_string2array($v['value']) : [];
        if (!is_array($value)) {
            $value = [];
        }
        $old = isset($value[SITE_ID][$aid]) && is_array($value[SITE_ID][$aid]) ? $value[SITE_ID][$aid] : [];
        // 兼容整型键
        if (!$old && is_numeric($aid) && isset($value[SITE_ID][intval($aid)]) && is_array($value[SITE_ID][intval($aid)])) {
            $old = $value[SITE_ID][intval($aid)];
            unset($value[SITE_ID][intval($aid)]);
        }
        unset($old['member'], $old['app']);
        $value[SITE_ID][$aid] = $old;

        \Phpcmf\Service::M()->db->table('member_setting')->replace([
            'name' => 'auth2',
            'value' => dr_array2string($value)
        ]);
        \Phpcmf\Service::M('cache')->sync_cache('member');

        $this->_json(1, dr_lang('本组权限初始化完成'));
    }

    // 兼容：单组详细设置（应用插件扩展权限）
    public function add() {

        $aid = \Phpcmf\Service::L('input')->get('aid');
        if ($aid == 'public') {
            $name = dr_lang('全局');
        } elseif (!$aid) {
            $aid = 0;
            $name = dr_lang('游客');
        } elseif (strpos($aid, '-') !== false) {
            list($gid, $lid) = explode('-', $aid);
            if (!$this->member_cache['group'][$gid]) {
                $this->_admin_msg(0, dr_lang('此用户组不存在'));
            } elseif (!$this->member_cache['group'][$gid]['level'][$lid]) {
                $this->_admin_msg(0, dr_lang('此用户组等级不存在'));
            }
            $name = $this->member_cache['group'][$gid]['name'].'-'.$this->member_cache['group'][$gid]['level'][$lid]['name'];
        } else {
            if (!$this->member_cache['group'][$aid]) {
                $this->_admin_msg(0, dr_lang('此用户组不存在'));
            }
            $name = $this->member_cache['group'][$aid]['name'];
        }

        $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray();
        $value = $v ? dr_string2array($v['value']) : [];
        if (!is_array($value)) {
            $value = [];
        }
        $data = isset($value[SITE_ID][$aid]) && is_array($value[SITE_ID][$aid]) ? $value[SITE_ID][$aid] : [];

        if (IS_AJAX_POST) {

            $post = \Phpcmf\Service::L('input')->post('data');
            if (!is_array($post)) {
                $post = [];
            }
            $save = $data;
            // 本页仅维护应用插件权限，禁止通过 POST 覆盖用户权限 member
            if (isset($post['app']) && is_array($post['app'])) {
                $save['app'] = $post['app'];
            }
            $value[SITE_ID][$aid] = $save;
            \Phpcmf\Service::M()->db->table('member_setting')->replace([
                'name' => 'auth2',
                'value' => dr_array2string($value)
            ]);
            \Phpcmf\Service::M('cache')->sync_cache('member');
            $this->_json(1, dr_lang('操作成功'));
        }

        $page = trim(\Phpcmf\Service::L('input')->get('page'));
        if (!$page) {
            $page = 'app';
        }

        \Phpcmf\Service::V()->assign([
            'aid' => $aid,
            'diy' => $this->_get_diy(),
            'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
                [
                    '返回' => ['member/auth/index', 'fa fa-cog'],
                    dr_lang('%s：应用权限', $name) => ['member/auth/add{aid='.$aid.'}', 'fa fa-puzzle-piece'],
                    'help' => [801],
                ]
            ),
            'page' => $page,
            'data' => $data,
            'is_ajax_edit' => 0,
        ]);
        \Phpcmf\Service::V()->display('member_auth_setting.html');
    }

    public function edit() {
        $this->_json(0, dr_lang('内容权限请到【内容系统 → 权限设置 → 内容权限】中配置'));
    }

    public function copy_edit() {

        $at = dr_safe_filename(\Phpcmf\Service::L('input')->get('at'));
        if (!$at) {
            $this->_json(0, dr_lang('at参数错误'));
        }

        $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray();
        $aid = dr_safe_filename(\Phpcmf\Service::L('input')->get('aid'));
        !$aid && $aid = 0;
        $value = dr_string2array($v['value']);

        switch ($at) {

            case 'level':
                $group = [
                    0 => [
                        'id' => 0,
                        'name' => dr_lang('游客'),
                    ],
                ];
                foreach ($this->member_cache['group'] as $t) {
                    $group[$t['id']] = [
                        'id' => $t['id'],
                        'name' => dr_lang($t['name']),
                    ];
                    if ($t['level']) {
                        foreach ($t['level'] as $lv) {
                            $group[$t['id'].'-'.$lv['id']] = [
                                'id' => $t['id'].'-'.$lv['id'],
                                'name' => '  └  '.dr_lang($lv['name']),
                            ];
                        }
                    }
                }

                if (IS_AJAX_POST) {

                    $auth = $value[SITE_ID][$aid];
                    if (!$auth) {
                        $this->_json(0, dr_lang('当前用户组没有配置权限规则'));
                    }

                    $catids = \Phpcmf\Service::L('input')->post('catid');
                    if (!$catids) {
                        $this->_json(0, dr_lang('你还没有选择用户组呢'));
                    }

                    $c = 0;
                    if (isset($catids[0]) && $catids[0] == 0) {
                        foreach ($group as $id => $t) {
                            $c ++;
                            $value[SITE_ID][$id] = $auth;
                        }
                    } else {
                        foreach ($catids as $id) {
                            $c ++;
                            $value[SITE_ID][$id] = $auth;
                        }
                    }

                    \Phpcmf\Service::M()->db->table('member_setting')->replace([
                        'name' => 'auth2',
                        'value' => dr_array2string($value)
                    ]);
                    \Phpcmf\Service::M('cache')->sync_cache('member');
                    $this->_json(1, dr_lang('共复制%s个用户组', $c));
                    exit;
                }

                \Phpcmf\Service::V()->assign([
                    'form' =>  dr_form_hidden(),
                    'select' => \Phpcmf\Service::L('tree')->select_category(
                        $group,
                        0,
                        'id=\'dr_catid\' name=\'catid[]\' multiple="multiple" style="height:200px"',
                        '',
                        0,
                        0
                    ),
                ]);
                \Phpcmf\Service::V()->display('member_auth_copy_group.html');exit;

            case 'group':
                $group = [
                    0 => [
                        'id' => 0,
                        'name' => dr_lang('游客'),
                    ],
                ];
                foreach ($this->member_cache['group'] as $t) {
                    $group[$t['id']] = $t;
                }

                if (IS_AJAX_POST) {

                    $auth = $value[SITE_ID][$aid];
                    if (!$auth) {
                        $this->_json(0, dr_lang('当前用户组没有配置权限规则'));
                    }

                    $catids = \Phpcmf\Service::L('input')->post('catid');
                    if (!$catids) {
                        $this->_json(0, dr_lang('你还没有选择用户组呢'));
                    }

                    $c = 0;
                    if (isset($catids[0]) && $catids[0] == 0) {
                        foreach ($group as $id => $t) {
                            $c ++;
                            $value[SITE_ID][$id] = $auth;
                        }
                    } else {
                        foreach ($catids as $id) {
                            $c ++;
                            $value[SITE_ID][$id] = $auth;
                        }
                    }

                    \Phpcmf\Service::M()->db->table('member_setting')->replace([
                        'name' => 'auth2',
                        'value' => dr_array2string($value)
                    ]);
                    \Phpcmf\Service::M('cache')->sync_cache('member');
                    $this->_json(1, dr_lang('共复制%s个用户组', $c));
                    exit;
                }

                \Phpcmf\Service::V()->assign([
                    'form' =>  dr_form_hidden(),
                    'select' => \Phpcmf\Service::L('tree')->select_category(
                        $group,
                        0,
                        'id=\'dr_catid\' name=\'catid[]\' multiple="multiple" style="height:200px"',
                        '',
                        0,
                        0
                    ),
                ]);
                \Phpcmf\Service::V()->display('member_auth_copy_group.html');exit;

            case 'share_category':
            case 'category':
                $this->_json(0, dr_lang('内容权限请到【内容系统 → 权限设置 → 内容权限】中配置'));
                break;

        }

        $this->_json(0, dr_lang('未知类型'));
    }

    private function _get_diy() {

        $diy = [
            'member' => [],
            'app' => [],
        ];

        $local = \Phpcmf\Service::Apps(1);
        foreach ($local as $dir => $path) {
            if (is_file($path.'Config/Auth.php')) {
                $_data = require $path.'Config/Auth.php';
                if ($_data) {
                    foreach ($_data as $key => $val) {
                        if ($val && isset($diy[$key])) {
                            foreach ($val as $file) {
                                if (is_file($path.'Views/auth/'.$file)) {
                                    $diy[$key][] = [
                                        'app' => $dir,
                                        'file' => $path.'Views/auth/'.$file,
                                    ];
                                } else {
                                    log_message('error', '应用插件['.$dir.']权限模板文件不存在：'.$path.'Views/auth/'.$file);
                                }
                            }
                        }
                    }
                }
            }
        }

        return $diy;
    }

}
