<?php

declare(strict_types=1);

namespace app\control\controller\account;

use app\BaseController;
use app\common\model\Base;
use app\Request;
use app\common\model\account\User as UserModel;
use mb\helper\Collection;
use mb\helper\Core;
use think\facade\App;
use think\response\Json;
use app\common\model\account\Department;
use app\common\model\account\Duty;
use app\control\model\User as CurrentUser;

/**
 * Class User
 * @package app\control\controller\Account
 */
class User extends BaseController
{
    /**
     * @param Request $request
     * @return Json
     * @api {post} /account/user/search 账号列表
     * @apiGroup Account
     * @apiName sort1
     * @apiVersion 1.0.0
     *
     * @apiDescription 账号列表
     *
     * @apiParam {number} current  页码
     * @apiParam {number} pageSize  页数
     * @apiParam {string} [department]  部门
     * @apiParam {string} [uid]  账号
     * @apiParam {string} [name]  姓名
     * @apiParam {string} [role]  类型 root 系统管理员 manager 管理员 user 用户
     * @apiParam {string} [status]  状态 normal - 正常 error - 禁用
     * @apiParam {number} [timeCreatedMax]  创建时间结束
     * @apiParam {number} [timeCreatedMin]  创建时间开始
     * @apiParam {number} [watch]  是否返回评卷类型
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function search(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        $pageIndex = empty($input['current']) ? 0 : intval($input['current']);
        $pageSize = empty($input['pageSize']) ? 10 : intval($input['pageSize']);
        $total = 0;
        $filters = [];
        $returnData = [];
        if ($currentUser['role'] != 'root') {
            $filters['founder'] = $currentUser['id'];
        }
        if (!empty($input['department'])) {
            $filters['department'] = $input['department'];
        }
        if (!empty($input['duty'])) {
            $filters['duty'] = $input['duty'];
        }
        if (!empty($input['uid'])) {
            $filters['uid'] = $input['uid'];
        }
        if (!empty($input['name'])) {
            $filters['name'] = $input['name'];
        }
        if (!empty($input['role'])) {
            $filters['role'] = $input['role'];
        }
        if (!empty($input['status'])) {
            $filters['status'] = $input['status'];
        }
        if (!empty($input['timeCreatedMax'])) {
            $filters['timeCreatedMax'] = $input['timeCreatedMax'];
        }
        if (!empty($input['timeCreatedMin'])) {
            $filters['timeCreatedMin'] = $input['timeCreatedMin'];
        }
        $dataSet = UserModel::search($filters, $pageIndex, $pageSize, $total);
        if (!empty($dataSet)) {
            $returnData = array_map(function ($row) use ($input) {
                if (!empty($input['watch'])) {
                    $row['watch'] = UserModel::getMarkExaminationPapers($row['id']);
                }
                return self::handelUserInfo($row);
            }, $dataSet);
        }
        return payload(['dataSet' => $returnData, 'total' => $total]);
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/add 添加账号
     * @apiGroup Account
     * @apiName sort3
     * @apiVersion 1.0.0
     *
     * @apiDescription 添加账号
     *
     * @apiParam {number} uid  账号
     * @apiParam {string} [password]  密码
     * @apiParam {number} gender  性别 1 - 男 2 - 女
     * @apiParam {number} department  部门
     * @apiParam {number} duty  职位
     * @apiParam {number} [birthday]  生日
     * @apiParam {number} [avatar]  头像
     * @apiParam {number} [phone]  手机号
     * @apiParam {number} [cardType]  证件类型
     * @apiParam {number} [cardNum]  证件号
     * @apiParam {number} [ip]  ip
     * @apiParam {number} [status]  状态 normal - 正常 error 禁用
     * @apiParam {number} [role]  admin - 管理员 user - 用户
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function add(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        if (
            empty($input['uid']) || empty($input['gender']) ||
            empty($input['department'])
        ) {
            return payload(error(-10, '缺少参数'));
        }
        $userExists = UserModel::fetch(['uid' => $input['uid']]);
        if (!empty($userExists)) {
            return payload(error(-20, '该账号已存在'));
        }
        $userInfo = [
            'uid' => $input['uid'],
            'name' => empty($input['name']) ? '' : $input['name'],
            'gender' => $input['gender'],
            'birthday' => empty($input['birthday']) ? 0 : strtotime($input['birthday']),
            'avatar' => empty($input['avatar']) ? '' : $input['avatar'],
            'department' => $input['department'],
            'duty' => empty($input['duty']) ? '' : $input['duty'],
            'phone' => empty($input['phone']) ? '' : $input['phone'],
            'cardType' => empty($input['cardType']) ? '' : $input['cardType'],
            'cardNum' => empty($input['cardNum']) ? '' : $input['cardNum'],
            'ip' => empty($input['ip']) ? '' : $input['ip'],
            'status' => empty($input['status']) ? 'normal' : $input['status'],
            'role' => (($currentUser['role'] == 'root') && !empty($input['role'])) ? $input['role'] : 'user',
            'salt' => Core::random(6),
            'founder' => $currentUser['id']
        ];
        $userInfo['password'] = empty($input['password']) ? '123456' : $input['password'];
        $userInfo['password'] = Base::encodePassword($userInfo['salt'], $userInfo['password']);
        $result = UserModel::add($userInfo);
        if (is_error($result)) {
            return payload(error(-21, '添加失败'));
        }
        return payload();
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/batchAdd 批量添加用户
     * @apiGroup Account
     * @apiName sort4
     * @apiVersion 1.0.0
     *
     * @apiDescription 批量添加用户
     *
     * @apiParam {number} startUid  开始编号
     * @apiParam {number} endUid  结束编号
     * @apiParam {number} department  部门ID
     * @apiParam {number} duty  职位ID
     * @apiParam {number} status  状态
     * @apiParam {number} role  只有manager权限 才能添加admin 其他为user
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     * @apiSuccess {Number} dataSet.success 成功次数
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"success":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function batchAdd(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        if (empty($input['startUid']) || empty($input['endUid']) || empty($input['status'])) {
            return payload(error(-10, '参数区间有误'));
        }
        $exists = UserModel::search(['minUid' => $input['startUid'],'maxUid' => $input['endUid']]);
        if (!empty($exists)) {
            return payload(error(-25,'该区间存在账号'));
        }
        $newRow = [
            'department' => empty($input['department']) ? 0 : $input['department'],
            'duty' => empty($input['duty']) ? 0 : $input['duty'],
            'founder' => $currentUser['id'],
            'status' => $input['status']
        ];
        $newRow['role'] = (($currentUser['role'] == 'root') && !empty($input['role'])) ? $input['role'] : 'user';
        $success = 0; //统计成功数值
        for ($i = $input['startUid']; $i <= $input['endUid']; $i++) {
            $newRow['uid'] = $i;
            $result = UserModel::add($newRow);
            if (!empty($result)) {
                $success++;
            }
        }
        return payload(['dataSet' => ['success' => $success]]);
    }

    public function import(Request $request)
    {
        $input = $request->post();
        if (empty($input['src'])) {
            return payload(error(-10, '缺少参数src'));
        }
        $result = UserModel::import(App::getRootPath() . 'public/' . $input['src']);
        if (!empty($result)) {
            return payload(['dataSet' => ['error' => $result]]);
        }
        return payload();
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/batchModify 批量修改用户
     * @apiGroup Account
     * @apiName sort2
     * @apiVersion 1.0.0
     *
     * @apiDescription 批量修改用户
     *
     * @apiParam {Object} ids 用户ID组
     * @apiParam {string} field 修改字段 支持 department-部门 duty-职务 status - 状态 delete - 删除
     * @apiParam {number} value 值
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function batchModify(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        if (
            empty($input['ids']) || empty($input['field']) || !in_array($input['field'], ['department', 'duty', 'status', 'delete'])
        ) {
            return payload(error(-10, '缺少参数'));
        }
        $filters = [
            'ids' => $input['ids']
        ];
        if ($currentUser['role'] != 'root') {
            $filters['founder'] = $currentUser['id'];
        }
        if ($input['field'] == 'delete') {
            UserModel::remove($filters);
        }
        if (in_array($input['field'], ['department', 'duty', 'status'])) {
            $newRow = [
                $input['field'] => $input['value'],
            ];
            UserModel::update($filters, $newRow);
        }
        return payload();
    }

    /**
     * 格式化用户数据 把部门 职位 创建人 格式化名称
     * @param $userInfo
     * @return mixed
     */
    protected static function handelUserInfo($userInfo)
    {
        $departmentInfo = Department::fetch(intval($userInfo['department']));
        if (!empty($departmentInfo)) {
            $userInfo['departmentTitle'] = $departmentInfo['title'];
        }
        $dutyInfo = Duty::fetch(intval($userInfo['duty']));
        if (!empty($dutyInfo)) {
            $userInfo['dutyTitle'] = $dutyInfo['title'];
        }
        if (($userInfo['founder'] != 0) && ($userInfo['role'] != 'root')) {
            $founderInfo = UserModel::fetch(intval($userInfo['founder']));
            if (!empty($founderInfo)) {
                $userInfo['founderTitle'] = $founderInfo['name'];
            }
        }
        return $userInfo;
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/modify 修改用户信息
     * @apiGroup Account
     * @apiName sort5
     * @apiVersion 1.0.0
     *
     * @apiDescription 修改用户信息
     *
     * @apiParam {number} id  id
     * @apiParam {number} [uid]  账号
     * @apiParam {string} [password]  密码
     * @apiParam {number} [gender]  性别
     * @apiParam {number} [department]  部门
     * @apiParam {number} [duty]  职位
     * @apiParam {number} [birthday]  生日
     * @apiParam {number} [avatar]  头像
     * @apiParam {number} [phone]  手机号
     * @apiParam {number} [cardType]  证件类型
     * @apiParam {number} [cardNum]  证件号
     * @apiParam {number} [ip]  ip
     * @apiParam {number} [status]  状态 normal - 正常 error 禁用
     * @apiParam {number} [role]  admin - 管理员 user - 用户
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function modify(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        if (empty($input['id'])) {
            return payload(error(-10, '缺少参数'));
        }
        $filters = [];
        $filters['id'] = $input['id'];
        $fields = [
            'name',
            'gender',
            'birthday',
            'avatar',
            'department',
            'duty',
            'company',
            'phone',
            'cardType',
            'cardNum',
            'role',
            'status',
            'ip',
        ];
        if ($currentUser['id'] != $input['id']) {
            if ($currentUser['role'] != 'root') {
                $filters['founder'] = $currentUser['id'];
            }
            $userExists = UserModel::fetch($filters);
            if (empty($userExists)) {
                return payload(error(-20, '未查到用户'));
            }
        } else {
            if ($currentUser['role'] != 'root') {
                $fields = array_diff($fields, ['department', 'duty', 'company', 'role', 'ip']);
            }
        }
        $newState = Collection::elements($fields, $input);
        if (!empty($newState['birthday'])) {
            $newState['birthday'] = strtotime($newState['birthday']);
        }
        if (!empty($input['password'])) {
            $newState['salt'] = Core::random(6);
            $newState['password'] = Base::encodePassword($newState['salt'], $input['password']);
        }
        $result = UserModel::update($filters, $newState);
        if (is_error($result)) {
            return payload(error(-21, '修改失败'));
        }
        return payload();
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/addMarkExaminationPapers 添加评卷账号
     * @apiGroup Account
     * @apiName sort6
     * @apiVersion 1.0.0
     *
     * @apiDescription 添加评卷账号
     *
     * @apiParam {Number} id  账号ID
     * @apiParam {Object} watch  权限
     * @apiParam {Object} watch.department  部门ID
     * @apiParam {Object} watch.user 用户ID
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function addMarkExaminationPapers(Request $request)
    {
        $input = $request->post();
        if (empty($input['id']) || empty($input['watch'])) {
            return payload(error(-10, '缺少参数'));
        }
        $data = [
            'department' => $input['watch']['department'],
            'user' => $input['watch']['user']
        ];
        $res = UserModel::addMarkExaminationPapers(['id' => $input['id']], $data);
        if (!$res) {
            return payload(error(-1, '评卷账号设置失败'));
        }
        return payload([]);
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/handel 修改评卷类型/权限
     * @apiGroup Account
     * @apiName sort7
     * @apiVersion 1.0.0
     *
     * @apiDescription 修改评卷类型/权限 <hr><br />
     * examType 类型：judge - 判断 fillIn - 填空 choice - 单选 choices - 复选
     * handel - 操作 composition - 作文 answer - 问答 typing - 打字 <br />
     * privileges 类型 : newsManger - 新闻管理 AccountManger - 账号管理
     * examManger 题库管理 testPaperManger 试卷管理 courseManger - 过程管理
     *
     * @apiParam {string} field  privileges - 权限 examType - 评卷类型
     * @apiParam {object} value  新值
     * @apiParam {Number} id  id
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function handel(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        if (empty($input['id']) || empty($input['field'])) {
            return payload(error(-10, '缺少参数'));
        }
        $input['value'] = empty($input['value']) ? [] : $input['value'];
        if (!in_array($input['field'], ['privileges', 'examType'])) {
            return payload(error(-11, '提交参数有误'));
        }
        $filters = [
            'founder' => $currentUser['id'],
            'id' => $input['id']
        ];
        $newState = [
            $input['field'] => serialize($input['value']),
        ];
        $result = UserModel::update($filters, $newState);
        if (!$result) {
            return payload(error(-20, '未发生修改,或修改失败'));
        }
        return payload();
    }

    /**
     * @param Request $request
     * @api {get} /account/user/export 导出账号列表
     * @apiGroup Account
     * @apiName sort8
     * @apiVersion 1.0.0
     *
     * @apiDescription 导出账号列表 导出为EXCEL文件
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     *
     */
    public function export(Request $request)
    {
        $input = $request->param();
        $currentUser = CurrentUser::fetchCurrent();
        $filters = [];
        if ($currentUser['role'] != 'root') {
            $filters = [
                'founder' => $currentUser['id']
            ];
        }
        if (!empty($input['uid'])) {
            $filters['uid'] = $input['uid'];
        }
        if (!empty($input['name'])) {
            $filters['name'] = $input['name'];
        }
        if (!empty($input['department'])) {
            $filters['department'] = $input['department'];
        }
        if (!empty($input['duty'])) {
            $filters['duty'] = $input['duty'];
        }
        if (!empty($input['role'])) {
            $filters['role'] = $input['role'];
        }
        if (!empty($input['status'])) {
            $filters['status'] = $input['status'];
        }
        $headers = [
            'uid',
            'name',
            'gender',
            'birthday',
            'department',
            'duty',
            'company',
            'phone',
            'cardType',
            'cardNum',
            'ip',
            'role',
            'status',
        ];
        UserModel::export($filters, $headers);
    }

    /**
     * @api {post} /account/user/loginOut 退出登录
     * @apiGroup sort9
     * @apiName Account
     * @apiVersion 1.0.0
     *
     * @apiDescription 退出登录
     *
     * @apiParam {number} current  页码
     * @apiParam {number} pageSize  页数
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[],"total":0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     *
     */
    public function loginOut()
    {
        session('exam_control', false);
        return payload();
    }

    /**
     * @param Request $request
     * @return Json
     *
     * @api {post} /account/user/updatePassword 修改密码
     * @apiGroup sort10
     * @apiName Account
     * @apiVersion 1.0.0
     *
     * @apiDescription 修改密码
     *
     * @apiParam {string} password  旧密码
     * @apiParam {string} newPass  新密码
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"errCode":0,"errMsg":"","dataSet":[]}
     *
     * @apiErrorExample {json} Error-Response:
     * {"errCode":5001,"errMsg":"接口异常"}
     */
    public function updatePassword(Request $request)
    {
        $currentUser = CurrentUser::fetchCurrent();
        $input = $request->post();
        $params = Base::existsParams($input, ['password', 'newPass']);
        if (is_error($params)) {
            return payload($params);
        }
        $userInfo = UserModel::fetch(intval($currentUser['id']));
        if (empty($userInfo['password']) || ($userInfo['password'] != Base::encodePassword($userInfo['salt'], $params['password']))) {
            return payload(error(-20, '旧密码错误'));
        }
        $newState = [
            'salt' => Core::random(6)
        ];
        $newState['password'] = Base::encodePassword($newState['salt'], $params['newPass']);
        UserModel::update(intval($userInfo['id']), $newState);
        return payload();
    }
}