<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-present http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;

use app\admin\model\UserModel;
use app\admin\service\RouteService;
use app\admin\service\SettingService;
use cmf\controller\AdminBaseController;

/**
 * Class SettingController
 * @package app\admin\controller
 * @adminMenuRoot(
 *     'name'   =>'设置',
 *     'action' =>'default',
 *     'parent' =>'',
 *     'display'=> true,
 *     'order'  => 0,
 *     'icon'   =>'cogs',
 *     'remark' =>'系统设置入口'
 * )
 */
class SettingController extends AdminBaseController
{

    /**
     * 网站信息
     * @adminMenu(
     *     'name'   => '网站信息',
     *     'parent' => 'default',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 0,
     *     'icon'   => '',
     *     'remark' => '网站信息',
     *     'param'  => ''
     * )
     */
    public function site()
    {
        $content = hook_one('admin_setting_site_view');

        if (!empty($content)) {
            return $content;
        }

        $noNeedDirs     = [".", "..", ".svn", 'fonts'];
        $adminThemesDir = WEB_ROOT . config('template.cmf_admin_theme_path') . config('template.cmf_admin_default_theme') . '/public/assets/themes/';
        $adminStyles    = cmf_scan_dir($adminThemesDir . '*', GLOB_ONLYDIR);
        $adminStyles    = array_diff($adminStyles, $noNeedDirs);
        $cdnSettings    = cmf_get_option('cdn_settings');
        $cmfSettings    = cmf_get_option('cmf_settings');
        $adminSettings  = cmf_get_option('admin_settings');

        $adminThemes = [];
        $themes      = cmf_scan_dir(WEB_ROOT . config('template.cmf_admin_theme_path') . '/*', GLOB_ONLYDIR);

        foreach ($themes as $theme) {
            if (strpos($theme, 'admin_') === 0) {
                array_push($adminThemes, $theme);
            }
        }

        if (APP_DEBUG && false) { // TODO 没确定要不要可以设置默认应用
            $apps = cmf_scan_dir($this->app->getAppPath() . '*', GLOB_ONLYDIR);
            $apps = array_diff($apps, $noNeedDirs);
            $this->assign('apps', $apps);
        }

        $this->assign('site_info', cmf_get_option('site_info'));
        $this->assign("admin_styles", $adminStyles);
        $this->assign("templates", []);
        $this->assign("admin_themes", $adminThemes);
        $this->assign("cdn_settings", $cdnSettings);
        $this->assign("admin_settings", $adminSettings);
        $this->assign("cmf_settings", $cmfSettings);

        return $this->fetch();
    }


    /**
     * 网站信息设置提交
     * @adminMenu(
     *     'name'   => '网站信息设置提交',
     *     'parent' => 'site',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '网站信息设置提交',
     *     'param'  => ''
     * )
     */
    public function sitePost()
    {
        if ($this->request->isPost()) {
            $result = $this->validate($this->request->param(), 'SettingSite');
            if ($result !== true) {
                $this->error($result);
            }

            $options = $this->request->param('options/a');
            if (!empty($options)) {
                cmf_set_option('site_info', $options);
            }

            $cmfSettings = $this->request->param('cmf_settings/a');
            if (!empty($cmfSettings)) {
                $bannedUsernames                 = preg_replace("/[^0-9A-Za-z_\\x{4e00}-\\x{9fa5}-]/u", ",", $cmfSettings['banned_usernames']);
                $cmfSettings['banned_usernames'] = $bannedUsernames;
                cmf_set_option('cmf_settings', $cmfSettings);
            }

            $cdnSettings = $this->request->param('cdn_settings/a');
            if (!empty($cdnSettings)) {
                cmf_set_option('cdn_settings', $cdnSettings);
            }

            $adminSettings = $this->request->param('admin_settings/a');

            if (!empty($adminSettings)) {
                if (!empty($adminSettings['admin_password'])) {
                    RouteService::setRoute($adminSettings['admin_password'] . '$', 'admin/Index/index', [], 2, 5000);
                } else {
                    RouteService::deleteRoute('admin/Index/index', []);
                }

                RouteService::getRoutes(true);
                if (!empty($adminSettings['admin_theme'])) {
                    $result = cmf_set_dynamic_config([
                        'template' => [
                            'cmf_admin_default_theme' => $adminSettings['admin_theme']
                        ]
                    ]);

                    if ($result === false) {
                        $this->error('配置写入失败!');
                    }
                }

                cmf_set_option('admin_settings', $adminSettings);
            }

            $this->success(lang('EDIT_SUCCESS'), '');

        }
    }


    /**
     * 后台设置
     * @adminMenu(
     *     'name'   => '后台设置',
     *     'parent' => 'default',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 0,
     *     'icon'   => '',
     *     'remark' => '后台设置',
     *     'param'  => ''
     * )
     */
    public function admin()
    {
        $content = hook_one('admin_setting_admin_view');

        if (!empty($content)) {
            return $content;
        }

        $noNeedDirs     = [".", "..", ".svn", 'fonts'];
        $adminThemesDir = WEB_ROOT . config('template.cmf_admin_theme_path') . config('template.cmf_admin_default_theme') . '/public/assets/themes/';
        $adminStyles    = cmf_scan_dir($adminThemesDir . '*', GLOB_ONLYDIR);
        $adminStyles    = array_diff($adminStyles, $noNeedDirs);
        $cdnSettings    = cmf_get_option('cdn_settings');
        $cmfSettings    = cmf_get_option('cmf_settings');
        $adminSettings  = cmf_get_option('admin_settings');

        $adminThemes = [];
        $themes      = cmf_scan_dir(WEB_ROOT . config('template.cmf_admin_theme_path') . '/*', GLOB_ONLYDIR);

        foreach ($themes as $theme) {
            if (strpos($theme, 'admin_') === 0) {
                array_push($adminThemes, $theme);
            }
        }

        if (APP_DEBUG && false) { // TODO 没确定要不要可以设置默认应用
            $apps = cmf_scan_dir($this->app->getAppPath() . '*', GLOB_ONLYDIR);
            $apps = array_diff($apps, $noNeedDirs);
            $this->assign('apps', $apps);
        }

        $this->assign('site_info', cmf_get_option('site_info'));
        $this->assign("admin_styles", $adminStyles);
        $this->assign("templates", []);
        $this->assign("admin_themes", $adminThemes);
        $this->assign("cdn_settings", $cdnSettings);
        $this->assign("admin_settings", $adminSettings);
        $this->assign("cmf_settings", $cmfSettings);

        return $this->fetch();
    }


    /**
     * 后台设置提交
     * @adminMenu(
     *     'name'   => '后台设置提交',
     *     'parent' => 'admin',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '后台设置提交',
     *     'param'  => ''
     * )
     */
    public function adminPost()
    {
        if ($this->request->isPost()) {
            $adminSettings = $this->request->param('admin_settings/a');

            if (!empty($adminSettings['admin_password'])) {
                RouteService::setRoute($adminSettings['admin_password'] . '$', 'admin/Index/index', [], 2, 5000);
            } else {
                RouteService::deleteRoute('admin/Index/index', []);
            }

            RouteService::getRoutes(true);

            if (!empty($adminSettings['admin_theme'])) {
                $result = cmf_set_dynamic_config([
                    'template' => [
                        'cmf_admin_default_theme' => $adminSettings['admin_theme']
                    ]
                ]);

                if ($result === false) {
                    $this->error('配置写入失败!');
                }
            }

            cmf_set_option('admin_settings', $adminSettings);

            $this->success(lang('EDIT_SUCCESS'));
        }
    }


    /**
     * 密码修改
     * @adminMenu(
     *     'name'   => '密码修改',
     *     'parent' => 'default',
     *     'display'=> false,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '密码修改',
     *     'param'  => ''
     * )
     */
    public function password()
    {
        return $this->fetch();
    }

    /**
     * 密码修改提交
     * @adminMenu(
     *     'name'   => '密码修改提交',
     *     'parent' => 'password',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '密码修改提交',
     *     'param'  => ''
     * )
     */
    public function passwordPost()
    {
        if ($this->request->isPost()) {

            $data = $this->request->param();
            if (empty($data['old_password'])) {
                $this->error("原始密码不能为空！");
            }
            if (empty($data['password'])) {
                $this->error("新密码不能为空！");
            }

            $userId = cmf_get_current_admin_id();

            $admin = UserModel::where("id", $userId)->find();

            $oldPassword = $data['old_password'];
            $password    = $data['password'];
            $rePassword  = $data['re_password'];

            if (cmf_compare_password($oldPassword, $admin['user_pass'])) {
                if ($password == $rePassword) {
                    if (cmf_compare_password($password, $admin['user_pass'])) {
                        $this->error("新密码不能和原始密码相同！");
                    } else {
                        UserModel::where('id', $userId)->update(['user_pass' => cmf_password($password)]);
                        $this->success("密码修改成功！");
                    }
                } else {
                    $this->error("密码输入不一致！");
                }

            } else {
                $this->error("原始密码不正确！");
            }
        }
    }

    /**
     * 上传限制设置界面
     * @adminMenu(
     *     'name'   => '上传设置',
     *     'parent' => 'default',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '上传设置',
     *     'param'  => ''
     * )
     */
    public function upload()
    {
        $uploadSetting = cmf_get_upload_setting();
        $this->assign('upload_setting', $uploadSetting);
        return $this->fetch();
    }

    /**
     * 上传限制设置界面提交
     * @adminMenu(
     *     'name'   => '上传设置提交',
     *     'parent' => 'upload',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '上传设置提交',
     *     'param'  => ''
     * )
     */
    public function uploadPost()
    {
        if ($this->request->isPost()) {
            //TODO 非空验证
            $uploadSetting = $this->request->post();

            cmf_set_option('upload_setting', $uploadSetting);
            $this->success(lang('EDIT_SUCCESS'));
        }

    }

    /**
     * 清除缓存
     * @adminMenu(
     *     'name'   => '清除缓存',
     *     'parent' => 'default',
     *     'display'=> false,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '清除缓存',
     *     'param'  => ''
     * )
     */
    public function clearCache()
    {
        $content = hook_one('admin_setting_clear_cache_view');

        if (!empty($content)) {
            return $content;
        }

        cmf_clear_cache();
        return $this->fetch();
    }



    /**
     * 多语言设置
     * @adminMenu(
     *     'name'   => '多语言设置',
     *     'parent' => 'default',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '多语言设置',
     *     'param'  => ''
     * )
     */
    public function lang()
    {
        $langSetting = app(SettingService::class)->getLangSetting();

        $this->assign('lang_setting', $langSetting);
        return $this->fetch();
    }


    /**
     * 多语言设置提交
     * @adminMenu(
     *     'name'   => '多语言设置提交',
     *     'parent' => 'lang',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '多语言设置提交',
     *     'param'  => ''
     * )
     */
    public function langPost()
    {
        $langSetting        = $this->request->param();
        $defaultLang        = empty($langSetting['default_lang']) ? 'zh-cn' : $langSetting['default_lang'];
        $adminDefaultLang   = empty($langSetting['admin_default_lang']) ? 'zh-cn' : $langSetting['admin_default_lang'];
        $allowLangList      = [];
        $adminAllowLangList = [];
        $langAliasList      = [];
        $langDomainList     = [];
        $acceptLanguageList = [];

        // 多语言模式;1:pathinfo前缀;2:域名;
        $multiLangMode = empty($langSetting['multi_lang_mode']) || $langSetting['multi_lang_mode'] == 1 ? 1 : 2;

        if (empty($langSetting['allow_lang_list'])) {
            $allowLangList                  = [$defaultLang];
            $langSetting['allow_lang_list'] = [[
                'lang'   => $defaultLang,
                'alias'  => '',
                'domain' => '',
                'enable' => 1,
            ]];
        } else {
            foreach ($langSetting['allow_lang_list'] as $allowLang) {
                if (empty($allowLang['lang'])) {
                    $this->error('前台语言包名不能为空！');
                }
                if (in_array($allowLang['lang'], $allowLangList)) {
                    $this->error('前台语言包名不能重复！');
                }
                if ($allowLang['lang'] == $defaultLang && empty($allowLang['enable'])) {
                    $this->error('前台默认语言包必须启用！');
                }

                if (!empty($allowLang['enable'])) {
                    $allowLangList[] = $allowLang['lang'];
                }

                if (!empty($allowLang['alias'])) {
                    if (in_array($allowLang['alias'], $langAliasList)) {
                        $this->error('前台语言别名不能重复！');
                    }
                    $langAliasList[$allowLang['lang']]       = $allowLang['alias'];
                    $acceptLanguageList[$allowLang['alias']] = $allowLang['lang'];
                }

                if (!empty($allowLang['domain'])) {
                    if (isset($langDomainList[$allowLang['domain']])) {
                        $this->error('前台语言域名不能重复！');
                    }
                    $langDomainList[$allowLang['domain']] = $allowLang['lang'];
                } else {
                    if ($multiLangMode == 2) {
                        $this->error('域名模式下语言域名不能为空！');
                    }
                }
            }
        }

        if (empty($langSetting['admin_allow_lang_list'])) {
            $allowLangList                        = [$adminAllowLangList];
            $langSetting['admin_allow_lang_list'] = [[
                'lang'   => $adminAllowLangList,
                'enable' => 1,
            ]];
        } else {
            foreach ($langSetting['admin_allow_lang_list'] as $allowLang) {
                if (empty($allowLang['lang'])) {
                    $this->error('后台语言包名不能为空！');
                }
                if (in_array($allowLang['lang'], $adminAllowLangList)) {
                    $this->error('后台语言包名不能重复！');
                }
                if ($allowLang['lang'] == $adminDefaultLang && empty($allowLang['enable'])) {
                    $this->error('后台默认语言包必须启用！');
                }
                if (!empty($allowLang['enable'])) {
                    $adminAllowLangList[] = $allowLang['lang'];
                }
            }
        }

        $result = cmf_set_dynamic_config([
            'lang' => [
                // 前台多语言开关
                'home_multi_lang'       => empty($langSetting['home_multi_lang']) ? 0 : 1,
                // 后台多语言开关
                'admin_multi_lang'      => empty($langSetting['admin_multi_lang']) ? 0 : 1,
                // 多语言模式;1:pathinfo前缀;2:域名;
                'multi_lang_mode'       => $multiLangMode,
                // 默认语言
                'default_lang'          => $defaultLang,
                // 允许的语言列表
                'allow_lang_list'       => $allowLangList,
                // 后台默认语言
                'admin_default_lang'    => $adminDefaultLang,
                // 后台允许的语言列表
                'admin_allow_lang_list' => $adminAllowLangList,
                // 语言包别名
                'lang_alias'            => $langAliasList,
                // 前台多语言域名列表
                'lang_domain_list'      => $langDomainList,
                // Accept-Language转义为对应语言包名称
                'accept_language'       => $acceptLanguageList,
            ]
        ]);
        if ($result === false) {
            $this->error('配置文件写入失败！');
        }
        cmf_set_option('lang_setting', $langSetting);
        $this->success(lang('EDIT_SUCCESS'));
    }


}
