<?php

declare(strict_types=1);

namespace app\control\controller\exam;

use app\BaseController;
use app\common\model\account\User as UserModel;
use app\common\model\exam\paper\Record;
use app\control\model\User;
use mb\helper\Collection;
use think\Exception;
use think\Request;
use think\response\Json;
use app\common\model\exam\Paper;

/**
 * Class Personal
 * @package app\control\controller\exam
 */
class Personal extends BaseController
{
    /**
     * @param Request $request
     * @return Json
     * @api {post} /exam/personal/search 成绩查询
     * @apiGroup Exam-personal
     * @apiName sort1
     * @apiVersion 1.0.0
     *
     * @apiDescription 成绩查询
     *
     * @apiParam {String} type 考试类型<br>competition -- 竞赛级别<br>promote -- 提升级<br>beginner -- 入门级<br>simulate -- 模拟考
     * @apiParam {Number} [current]  页码
     * @apiParam {Number} [pageSize]  页数
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"code":0,"message":"","dataSet":[], "total" : 0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"code":5001,"message":"接口异常"}
     */
    public function search(Request $request)
    {
        $input = $request->post();
        $user = User::fetchCurrent();
        $pageIndex = empty($input['current']) ? 1 : intval($input['current']);
        $pageSize = empty($input['pageSize']) ? 10 : intval($input['pageSize']);
        $total = 0;
        $filters = [];
        $type = empty($input['type']) ? '' : $input['type'];
        $filters['type'] = $type;
        $filters['status'] = 'end';
        $filters['userId'] = $user['id'];
//        $filters['personal'] = 1;
        if (!empty($input['title'])) {
            $filters['title'] = $input['title'];
        }
        if (!empty($input['timeStart'])) {
            $filters['timeStart'] = $input['timeStart'];
        }
        if (!empty($input['timeEnd'])) {
            $filters['timeEnd'] = $input['timeEnd'];
        }
        $dataSet = Record::search($filters, $pageIndex, $pageSize, $total);
        $dataSet = array_map(
            function ($rec) {
                $rec['pass'] = ($rec['score'] > $rec['throughPoints']) ? true : false;
                if ($rec['markId']) {
                    $userInfo = UserModel::fetch($rec['markId']);
                    $rec['markTitle'] = isset($userInfo['uid']) ? $userInfo['uid'] : '';
                } else {
                    $rec['markTitle'] = '';
                }
                $rec = Collection::elements(
                    [
                        'id',
                        'paperId',
                        'userId',
                        'status',
                        'pass',
                        'score',
                        'totalPoints',
                        'timeEnd',
                        'title',
                        'markTitle',
                        'markStatus'
                    ],
                    $rec
                );
                return $rec;
            },
            $dataSet
        );
        $pass = Record::passNum($type);
        return payload(['dataSet' => $dataSet, 'total' => $total, 'pass' => $pass]);
    }

    /**
     * @param Request $request
     * @return Json
     * @throws Exception
     * @api {post} /exam/personal/statistics 统计
     * @apiGroup Exam-personal
     * @apiName sort2
     * @apiVersion 1.0.0
     *
     * @apiDescription 统计
     *
     * @apiParam {Number} id  成绩id
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"code":0,"message":"","dataSet":[], "total" : 0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"code":5001,"message":"接口异常"}
     */
    public function statistics(Request $request)
    {
        $input = $request->post();
        if (empty($input['id'])) {
            return payload(error(-1, '参数不完整'));
        }
        $user = User::fetchCurrent();
        $records = Record::fetch(intval($input['id']));
        $paper = Paper::fetch($records['paper_id']);
        $strategies = unserialize($paper['strategies']);
        $questionType = unserialize($paper['question_type']);
        $questionType = array_map(function ($q) {
            $q = $q['point'];
            return $q;
        }, $questionType); //题型对应分值
        $knowledge = [];
        foreach ($strategies as $val) {
            $knowledge[$val['knowledge']][] = $val;
        }
        $newKnowledge = [];
        foreach ($knowledge as $k) {
            if (!isset($newKnowledge[$k[0]['knowledge']])) {
                $newKnowledge[$k[0]['knowledge']] = [
                    'knowledge' => $k[0]['knowledge'],
                    'subject' => $k[0]['subject'],
                    'knowledgeTitle' => $k[0]['knowledgeTitle'],
                    'subjectTitle' => $k[0]['subjectTitle'],
                    'num' => 0,
                    'score' => 0,
                    'userScore' => 0,
                    'percent' => 0,
                    'pass' => 0,
                ];
                foreach ($k as $v) {
                    if ($paper['mode'] == 'hand') {
                        $num = count($v['strategy']);
                    } else {
                        $num = array_sum($v['strategy']);
                    }
                    $newKnowledge[$k[0]['knowledge']]['num'] += $num;
                    $score = $num * $questionType[$v['type']];
                    $newKnowledge[$k[0]['knowledge']]['score'] += $score;
                }
            }
        }
        $result = unserialize($records['result']);
        $arr = [];
        foreach ($result as $value) {
            $arr = array_merge($arr, $value);
        }
        $result = $arr;
        $questionNum = 0;
        foreach ($result as $know) {
            if ($know['score'] > 0) {
                $newKnowledge[$know['knowledge']]['userScore'] += $know['score'];
                $newKnowledge[$know['knowledge']]['pass']++;
            }
            $questionNum++;
        }
        $newKnowledge = array_map(function ($last) {
            $last['percent'] = sprintf("%.2f", ($last['pass'] / $last['num']) * 100) ;
            return $last;
        }, $newKnowledge);
        $returnData = [
            'title' => $paper['title'],
            'totalPoints' => $paper['total_points'],
            'throughPoints' => $paper['through_points'],
            'timeEnd' => $records['time_end'],
            'score' => $records['score'],
            'userId' => $user['uid'],
            'name' => $user['name'],
            'questionNum' => $questionNum,
            'dataSet' => array_values($newKnowledge)
        ];
        return payload(['data' => $returnData]);
    }

    /**
     * @param Request $request
     * @return Json
     * @throws Exception
     * @api {post} /exam/personal/statisticsDetail 试卷统计（具体）
     * @apiGroup Exam-personal
     * @apiName sort5
     * @apiVersion 1.0.0
     *
     * @apiDescription 统计
     *
     * @apiParam {Number} id  成绩id
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"code":0,"message":"","dataSet":[], "total" : 0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"code":5001,"message":"接口异常"}
     */
    public function statisticsDetail(Request $request)
    {
        $input = $request->post();
        if (empty($input['id'])) {
            return payload(error(-1, '参数不完整'));
        }
        $records = Record::fetch(intval($input['id']));
        $paper = Paper::fetch($records['paper_id']);
        $strategies = unserialize($paper['strategies']);
        $questionType = unserialize($paper['question_type']);
        $questionType = array_map(
            function ($q) {
                $q = $q['point'];
                return $q;
            },
            $questionType
        ); //题型对应分值
        $knowledge = [];
        foreach ($strategies as $val) {
            $knowledge[$val['knowledge']][] = $val;
        }
        $newKnowledge = [];
        foreach ($knowledge as $k) {
            if (!isset($newKnowledge[$k[0]['knowledge']])) {
                $newKnowledge[$k[0]['knowledge']] = [
                    'knowledge' => $k[0]['knowledge'],
                    'subject' => $k[0]['subject'],
                    'knowledgeTitle' => $k[0]['knowledgeTitle'],
                    'subjectTitle' => $k[0]['subjectTitle'],
                    'num' => 0,
                    'score' => 0,
                    'userScore' => 0,
                    'percent' => 0,
                    'pass' => 0,
                ];
                foreach ($k as $v) {
                    if ($paper['mode'] == 'hand') {
                        $num = count($v['strategy']);
                    } else {
                        $num = array_sum($v['strategy']);
                    }
                    $newKnowledge[$k[0]['knowledge']]['num'] += $num;
                    $score = $num * $questionType[$v['type']];
                    $newKnowledge[$k[0]['knowledge']]['score'] += $score;
                }
            }
        }
        $result = unserialize($records['result']);
        $arr = [];
        foreach ($result as $value) {
            $arr = array_merge($arr, $value);
        }
        $result = $arr;
        $questionNum = 0;
        foreach ($result as $know) {
            if ($know['score'] > 0) {
                $newKnowledge[$know['knowledge']]['userScore'] += $know['score'];
                $newKnowledge[$know['knowledge']]['pass']++;
            }
            $questionNum++;
        }
        $newKnowledge = array_map(
            function ($last) {
                $last['percent'] = sprintf("%.2f", $last['pass'] / $last['num']) * 100;
                return $last;
            },
            $newKnowledge
        );
        $user = UserModel::fetch($records['user_id']);
        $returnData = [
            'title' => $paper['title'],
            'totalPoints' => $paper['total_points'],
            'throughPoints' => $paper['through_points'],
            'timeEnd' => $records['time_end'],
            'score' => $records['score'],
            'userId' => $user['uid'],
            'name' => '',
            'questionNum' => $questionNum,
            'dataSet' => array_values($newKnowledge)
        ];
        if (!empty($user['name'])) {
            $returnData['name'] = $user['name'];
        }
        return payload(['data' => $returnData]);
    }

    /**
     * @param Request $request
     * @return Json
     * @throws Exception
     * @api {post} /exam/personal/ranking 排名
     * @apiGroup Exam-personal
     * @apiName sort3
     * @apiVersion 1.0.0
     *
     * @apiDescription 排名
     *
     * @apiParam {Number} id  成绩id
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"code":0,"message":"","dataSet":[], "total" : 0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"code":5001,"message":"接口异常"}
     */
    public function ranking(Request $request)
    {
        $input = $request->post();
        if (empty($input['id'])) {
            return payload(error(-1, '参数不完整'));
        }
        $records = Record::fetch(intval($input['id']));
        if (empty($records)) {
            return payload(error(-12, '系统故障'));
        }
        $rank = Record::serial($records['paper_id'], intval($records['id']));
        return payload(['rank' => $rank]);
    }

    /**
     * @param Request $request
     * @return Json
     * @throws Exception
     * @api {post} /exam/personal/preview 答卷
     * @apiGroup Exam-personal
     * @apiName sort4
     * @apiVersion 1.0.0
     *
     * @apiDescription 答卷
     *
     * @apiParam {Number} id  成绩id
     * @apiParam {String} type 显示模式 all --整卷 wrong--错题
     *
     * @apiSuccess {Number} code    状态码，0：请求成功
     * @apiSuccess {String} message   提示信息
     * @apiSuccess {Object} dataSet    返回数据
     *
     * @apiSuccessExample {json} Success-Response:
     * {"code":0,"message":"","dataSet":[], "total" : 0}
     *
     * @apiErrorExample {json} Error-Response:
     * {"code":5001,"message":"接口异常"}
     */
    public function preview(Request $request)
    {
        $input = $request->post();
        if (empty($input['id']) || empty($input['type'])) {
            return payload(error(-11, '参数不完整'));
        }
        $type = ($input['type'] == 'all') ? 'all' : 'wrong';
        $dataSet = Record::preview(intval($input['id']), $type);
        return payload(['data' => $dataSet]);
    }
}