<?php
/** 随机前缀临时表验证，不写入实际员工/班组。 */
if (PHP_SAPI !== 'cli') exit;
require dirname(__DIR__).'/vendor/autoload.php';
use think\facade\Db;
use think\exception\HttpResponseException;
use app\mobile\controller\OmsTeam;
use think\facade\Cache;

$app = new \think\App(dirname(__DIR__).'/');
$app->initialize();
set_exception_handler(function ($error) { fwrite(STDERR,$error->getMessage()."\n"); exit(1); });
$database = $app->config->get('database');
$original = $database['connections'][$database['default']];
if (!in_array($original['hostname'], ['127.0.0.1','localhost'], true)) throw new RuntimeException('Tests require a local database');
$prefix = 'team_test_'.bin2hex(random_bytes(4)).'_';
$connection = $original; $connection['prefix'] = $prefix;
$database['connections']['team_test'] = $connection; $database['default'] = 'team_test';
$app->config->set($database,'database'); Db::setConfig($app->config);
$tables = ['team_list','team_base','member_list','admin_user','auth','member_interview','team_plan_position','admin_org'];
$created = []; $tokens = []; $checks = 0;
function checkTeam($condition,$label) { global $checks; if (!$condition) throw new RuntimeException($label); $checks++; }
function seedTeam($table,$data) {
    global $prefix;
    foreach (Db::query('SHOW COLUMNS FROM `'.$prefix.$table.'`') as $field) {
        if (!array_key_exists($field['Field'],$data) && $field['Null']==='NO' && $field['Default']===null && $field['Extra']!=='auto_increment') {
            $data[$field['Field']] = preg_match('/int|float|decimal|double/',$field['Type']) ? 0 : '';
        }
    }
    Db::name($table)->insert($data);
}
function invokeTeam($action,$id,$data=[],$token='') {
    global $app;
    $request = new \think\Request();
    $request->withServer(['REQUEST_METHOD'=>$action==='index'?'GET':'POST']);
    $request->withPost($data)->withHeader(['authorization'=>$token ? 'Bearer '.$token : '']);
    $app->instance('request',$request);
    try { $response = (new OmsTeam($app))->$action(); }
    catch (HttpResponseException $error) { $response = $error->getResponse(); }
    return [$response->getCode(),json_decode($response->getContent(),true)];
}
try {
    foreach ($tables as $table) {
        Db::execute('CREATE TABLE `'.$prefix.$table.'` LIKE `'.$original['prefix'].$table.'`');
        $created[] = $table;
    }
    seedTeam('team_base',['id'=>1,'title'=>'项目甲','mid'=>1]);
    seedTeam('team_base',['id'=>2,'title'=>'产线甲','mid'=>2]);
    seedTeam('team_base',['id'=>3,'title'=>'项目乙','mid'=>1]);
    seedTeam('team_base',['id'=>4,'title'=>'产线乙','mid'=>2]);
    foreach ([1,2,3] as $id) seedTeam('team_list',['id'=>$id,'team'=>'班组'.$id,'project'=>$id===1?1:3,'line'=>$id===1?2:4,'aid'=>21,'shift'=>$id===1?1:2,'status'=>$id===3?2:1]);
    foreach ([11,12] as $id) seedTeam('member_list',['id'=>$id,'eid'=>'team-'.$id,'ename'=>'员工'.$id,'tid'=>1,'status'=>1,'poid'=>0]);
    foreach ([21,22,23] as $id) seedTeam('admin_user',['id'=>$id,'username'=>'team-'.$id,'truename'=>'班长'.$id,'job'=>$id===23?18:9,'status'=>1]);
    foreach ([11,12,21,22,23] as $id) seedTeam('auth',['id'=>$id,'username'=>'team-'.$id,'user_id'=>$id<20?$id:0,'admin_id'=>$id<20?0:$id,'user_type'=>$id<20?1:($id===22?2:3),'openid'=>'synthetic-team-'.$id,'status'=>1,'version'=>1]);
    $db = $app->config->get('database.connections.team_test.database');
    foreach ([11,12,21,22,23] as $id) {
        $tokens[$id] = bin2hex(random_bytes(32));
        Cache::store('redis')->set('wxoms-v3:'.$db.':session:'.hash('sha256',$tokens[$id]),['id'=>$id,'version'=>1,'expires_at'=>time()+60],60);
    }
    foreach ([21,24] as $id) {
        if ($id===24) seedTeam('admin_user',['id'=>$id,'username'=>'team-'.$id,'truename'=>'新增人员'.$id,'job'=>9,'status'=>1]);
        Db::name('admin_user')->where('id',$id)->update(['password'=>md5('test-password')]);
        $request=new \think\Request();$request->withServer(['REQUEST_METHOD'=>'POST']);
        $request->withPost(['username'=>'team-'.$id,'password'=>'test-password','code'=>'local-test']);$app->instance('request',$request);
        $controller=new class($app) extends \app\mobile\controller\OmsAuth { protected function wechatOpenid($code) { return 'synthetic-'.$this->request->post('username'); } };
        $response=$controller->login();$body=json_decode($response->getContent(),true);
        checkTeam($response->getCode()===200&&isset($body['data']['token']),'已有和新增账号登录成功');
        $tokens[]=$body['data']['token'];
        checkTeam(Db::name('auth')->where('username','team-'.$id)->value('name')===$body['data']['profile']['name'],'已有和新增账号登录保存auth.name');
    }
    [$status] = invokeTeam('index',11); checkTeam($status===401,'无凭证不能加载');
    [$status] = invokeTeam('join',11,['id'=>2]); checkTeam($status===401,'无凭证不能修改');
    [$status,$body] = invokeTeam('index',11,[],$tokens[11]);
    checkTeam($status===200 && $body['data']['isEmployee'] && $body['data']['canJoin'],'一线员工可以加入');
    checkTeam(count($body['data']['teams'])===2,'全部有效班组，包含不同项目');
    checkTeam($body['data']['currentTeam']['team']==='班组1' && $body['data']['currentTeam']['aid_name']==='班长21','顶部当前班组及班长');
    checkTeam($body['data']['teams'][1]['project_name']==='项目乙' && $body['data']['teams'][1]['line_name']==='产线乙' && $body['data']['teams'][1]['shift_name']==='夜班','项目产线班次名称');
    [$status,$body] = invokeTeam('join',11,['id'=>2,'aid'=>23,'mid'=>12],$tokens[11]);
    checkTeam($status===200 && $body['data']['changed'] && $body['data']['isEmployee'],'员工加入成功');
    checkTeam($body['data']['profile']['team']==='班组2' && $body['data']['profile']['leader']==='班长21','新版profile同步新班组与班长');
    checkTeam(Db::name('auth')->where('id',11)->value('name')==='员工11','员工资料同步auth.name');
    checkTeam((int)Db::name('member_list')->where('id',11)->value('tid')===2 && (int)Db::name('member_list')->where('id',12)->value('tid')===1,'只能修改本人，忽略伪造mid');
    checkTeam((int)Db::name('team_list')->where('id',2)->value('aid')===21,'员工加入不改班长');
    [$status,$body] = invokeTeam('join',11,['id'=>2],$tokens[11]); checkTeam(!$body['data']['changed'],'重复加入幂等');
    [$status] = invokeTeam('join',11,['id'=>3],$tokens[11]); checkTeam($status===409,'不能加入停用班组');
    [$status] = invokeTeam('join',11,['id'=>999],$tokens[11]); checkTeam($status===409,'不能加入不存在班组');
    foreach ([0,-1,'2x',[],2147483648] as $id) { [$status] = invokeTeam('join',11,['id'=>$id],$tokens[11]); checkTeam($status===400,'非法编号拒绝'); }
    [$status,$body] = invokeTeam('index',23,[],$tokens[23]); checkTeam(!$body['data']['isEmployee'] && !$body['data']['canJoin'],'非9岗位不允许认领');
    [$status] = invokeTeam('join',23,['id'=>2,'aid'=>22,'job'=>9],$tokens[23]); checkTeam($status===403,'伪造job和aid不能认领');
    [$status,$body] = invokeTeam('join',22,['id'=>2,'aid'=>23],$tokens[22]);
    checkTeam($status===200 && $body['data']['changed'] && !$body['data']['isEmployee'] && $body['data']['team']['aid']===22,'job9按本人admin_id认领');
    checkTeam(Db::name('auth')->where('id',22)->value('name')==='班长22','管理人员资料同步auth.name');
    checkTeam((int)Db::name('member_list')->where('id',11)->value('tid')===2,'班长认领不修改人员班组');
    [$status,$body] = invokeTeam('index',11,[],$tokens[11]); checkTeam($body['data']['currentTeam']['aid_name']==='班长22','重新进入获取新班长');
    [$status,$body] = invokeTeam('join',22,['id'=>2],$tokens[22]); checkTeam(!$body['data']['changed'],'重复认领幂等');
    Db::name('admin_user')->where('id',22)->update(['job'=>18]);
    [$status] = invokeTeam('join',22,['id'=>1],$tokens[22]); checkTeam($status===403,'实时校验岗位变更');
    Db::name('auth')->where('id',11)->inc('version')->update(['openid'=>null]);
    [$status] = invokeTeam('join',11,['id'=>1],$tokens[11]); checkTeam($status===401,'微信解绑后旧凭证失效');
    echo 'PASS '.$checks." team checks\n";
} finally {
    if (isset($db)) foreach ($tokens as $token) Cache::store('redis')->delete('wxoms-v3:'.$db.':session:'.hash('sha256',$token));
    foreach (array_reverse($created) as $table) Db::execute('DROP TABLE `'.$prefix.$table.'`');
}
