<?php
/** 隔离转移表、auth 表 + 模拟微信发送；不发送真实消息、不改业务记录。 */
if(PHP_SAPI!=='cli')exit;
require dirname(__DIR__).'/vendor/autoload.php';
use think\facade\Db;
use think\facade\Cache;
class SuggestionNoticeFake extends \app\mobile\service\WechatTemplateService {
    public $calls=[];
    public function admins($ids){return array_map(function($id){return 'test-'.$id;},$ids);}
    public function send($template,$recipients,$values,$page){$this->calls[]=[$template,$recipients,$this->payload($template,$values,$page)];return true;}
    protected function setting($key){return $key==='appid'?'test-mini':'';}
}
class SuggestionNoticeController extends \app\mobile\controller\OmsSuggestion {
    public $fake;
    protected function templateService(){return $this->fake;}
    public function emit($row,$title){return $this->notify($row,$title,[]);}
}
class SuggestionAdminNoticeFake extends \app\adminVue\controller\V2SuggestionNotice {
    public $sent=[];public $appid;
    protected function settings(){return ['template'=>'test-template','appid'=>$this->appid,'secret'=>'test-secret','mini'=>'test-mini'];}
    protected function request($url,$data){$this->sent[]=$data;return strpos($url,'stable_token')!==false?['access_token'=>'test-token','expires_in'=>120]:['errcode'=>0];}
}
$app=new \think\App(dirname(__DIR__).'/');$app->initialize();
set_exception_handler(function($e){fwrite(STDERR,$e->getMessage().PHP_EOL);exit(1);});
$config=config('database');$connection=$config['connections'][$config['default']];
if(!in_array($connection['hostname'],['localhost','127.0.0.1'],true))throw new RuntimeException('Local database required');
$original=$connection['prefix'];$prefix='suggestion_notice_'.bin2hex(random_bytes(5)).'_';$connection['prefix']=$prefix;$connection['fields_cache']=false;
$config['connections']['notice_test']=$connection;$config['default']='notice_test';$app->config->set($config,'database');Db::setConfig($app->config);
function noticeCheck($ok,$message){if(!$ok)throw new RuntimeException($message);echo 'PASS: '.$message.PHP_EOL;}
$created=[];$admin=new SuggestionAdminNoticeFake();$admin->appid='suggestion-notice-test-'.bin2hex(random_bytes(6));
try{
    foreach(['onsite_suggestion_transfer','auth'] as $table){Db::execute('CREATE TABLE `'.$prefix.$table.'` LIKE `'.$original.$table.'`');$created[]=$table;}
    $controller=new SuggestionNoticeController($app);$controller->fake=new SuggestionNoticeFake();$service=$controller->fake;
    $row=['id'=>88,'owner'=>2,'status'=>2];
    foreach(['指定您为反馈责任人','部门窗口指定您为反馈责任人'] as $title){
        noticeCheck($controller->emit($row,$title),'assignment payload generated');$call=end($service->calls);
        noticeCheck($call[0]==='work_order_pending'&&$call[1]===['test-2'],'assignment uses work-order template for assigned owner');
        noticeCheck($call[2]['data']['thing9']['value']==='分配给你，请及时反馈'&&$call[2]['data']['thing15']['value']==='合理化建议·待反馈','assignment clearly requires feedback and no acceptance');
    }
    $tid=Db::name('onsite_suggestion_transfer')->insertGetId(['suggestion_id'=>88,'from_owner'=>2,'to_owner'=>3,'from_name'=>'原负责人','to_name'=>'接收人','from_department'=>'生产部','to_department'=>'设备部','reason'=>'设备改造需专业跟进','reply'=>'','state'=>'pending','created_at'=>time()]);
    $row+=['transfer_id'=>$tid,'transfer_to'=>3];$controller->emit($row,'合理化建议待接收');$call=end($service->calls);
    noticeCheck($call[0]==='workflow_pending'&&$call[1]===['test-3'],'transfer uses separate workflow template for proposed receiver');
    noticeCheck($call[2]['data']['thing3']['value']==='原负责人'&&$call[2]['data']['thing16']['value']==='设备改造需专业跟进'&&$call[2]['data']['thing9']['value']==='请确认接收或拒绝转移','transfer includes initiator, reason and required acceptance');
    noticeCheck($call[2]['miniprogram']['pagepath']==='pages/suggestion/detail?id=88','transfer opens correct suggestion');
    Db::name('onsite_suggestion_transfer')->where('id',$tid)->update(['state'=>'cancelled']);$before=count($service->calls);$controller->emit($row,'合理化建议待接收');
    noticeCheck(count($service->calls)===$before,'cancelled transfer does not emit stale acceptance request');
    $auth=['username'=>'test-notice','admin_id'=>2,'user_type'=>3,'status'=>1,'gzhOpenid'=>'fake-recipient'];
    foreach(Db::query('SHOW COLUMNS FROM `'.$prefix.'auth`') as $field)if(!array_key_exists($field['Field'],$auth)&&$field['Null']==='NO'&&$field['Default']===null&&$field['Extra']!=='auto_increment')$auth[$field['Field']]=preg_match('/int|float|double|decimal/',$field['Type'])?0:'';
    Db::name('auth')->insert($auth);$result=$admin->send(['id'=>88,'owner'=>2,'ename'=>'提报人']);$sent=end($admin->sent);
    noticeCheck($result['status']==='sent'&&$sent['data']['keyword3']['value']==='分配给你，请及时反馈','admin assignment also explicitly needs no acceptance');
    echo "Suggestion notice payload checks passed; no real messages sent.\n";
}finally{
    Cache::delete('admin-v2:suggestion-notice:'.hash('sha256',$admin->appid));
    foreach(array_reverse($created) as $table)Db::execute('DROP TABLE IF EXISTS `'.$prefix.$table.'`');
}
