<?php
// 只使用本机数据库的随机临时表，不修改真实考试成绩。
if (PHP_SAPI !== 'cli') exit;
require dirname(__DIR__).'/vendor/autoload.php';
use think\facade\Db;
use app\admin\model\MemberNewcomerExam;
use app\mobile\controller\OmsExam;
use think\exception\HttpResponseException;

$app = new \think\App(dirname(__DIR__).'/');
$app->initialize();
$config = $app->config->get('database');
$connection = $config['connections'][$config['default']];
if (!in_array($connection['hostname'], ['localhost','127.0.0.1'], true)) throw new RuntimeException('Local database required');
$prefix = 'exam_test_'.bin2hex(random_bytes(4)).'_';
$originalPrefix = $connection['prefix'];
$connection['prefix'] = $prefix;
$config['connections']['exam_test'] = $connection;
$config['default'] = 'exam_test';
$app->config->set($config, 'database');
Db::setConfig($app->config);
$created = [];
function checkExam($condition, $message) {
    if (!$condition) throw new RuntimeException($message);
}
function invokeExam($action, $data) {
    global $app;
    $request = new \think\Request();
    $request->withServer(['REQUEST_METHOD'=>'POST'])->withPost($data);
    $app->instance('request', $request);
    try { $response = (new OmsExam($app))->$action(); }
    catch (HttpResponseException $e) { $response = $e->getResponse(); }
    return json_decode($response->getContent(), true);
}
try {
    foreach (['member_newcomer_score','member_newcomer_exam'] as $table) {
        Db::execute('CREATE TABLE `'.$prefix.$table.'` LIKE `'.$originalPrefix.$table.'`');
        $created[] = $table;
    }
    $data = ['ename'=>'考试测试','phone'=>'13900000001','item_type'=>1,'score'=>79.5,'answers'=>'{}'];
    $first = MemberNewcomerExam::saveScore($data);
    checkExam($first['code'] === 1, '79.5 must fail');
    // 昨天的记录仍计入总次数；改姓名也不能重置。
    Db::name('member_newcomer_score')->where('id',$first['scoreId'])->update(['exam_date'=>strtotime('yesterday')]);
    $data['ename'] = '更名测试'; $data['score'] = 80;
    $second = MemberNewcomerExam::saveScore($data);
    checkExam($second['code'] === 0, '80 must pass');
    checkExam((int)Db::name('member_newcomer_score')->where('id',$second['scoreId'])->value('status') === 1, 'Pass status must be saved');
    checkExam(MemberNewcomerExam::saveScore($data)['code'] === 0, 'Third submission must be accepted');
    checkExam(MemberNewcomerExam::attemptCount($data['phone']) === 3, 'Third submission must insert');
    $paper = (new MemberNewcomerExam())->online_exam($data);
    checkExam($paper['code'] === 0, 'Legacy start must allow more than two attempts');
    $data['phone'] = '13900000002';
    $data['answer'] = [['id'=>1,'answered'=>'A']];
    $new = invokeExam('submit', $data);
    checkExam($new['code'] === 0 && $new['data']['passed'], 'New submit must use 80 point rule');
    $data['score'] = 79.5;
    $new = invokeExam('submit', $data);
    checkExam($new['code'] === 0 && !$new['data']['passed'], 'New submit must fail below 80');
    checkExam(invokeExam('submit', $data)['code'] === 0, 'New submit must allow third attempt');
    checkExam(MemberNewcomerExam::attemptCount($data['phone']) === 3, 'New third attempt must insert');
    echo "Newcomer exam 80-point boundary and unlimited retry API checks passed.\n";
} finally {
    foreach (array_reverse($created) as $table) Db::execute('DROP TABLE IF EXISTS `'.$prefix.$table.'`');
}
