<?php
declare(strict_types=1);
require __DIR__.'/../vendor/autoload.php';
define('TP_ENV','test');define('BUSINESS','upgrade_gift_fixture');
class UpgradeGiftOrder extends ArrayObject {
 static $current;
 static function where(...$args){return self::$current;}
 function lock($x){return $this;}
 function find(){return $this;}
 function startTrans(){\think\facade\Db::startTrans();}
 function commit(){\think\facade\Db::commit();}
 function rollback(){\think\facade\Db::rollback();}
 function save($data){foreach($data as $k=>$v)$this[$k]=$v;return true;}
}
class UpgradeGiftGuard {function assertLocalWalletAllowedByAiUserId($id){}}
class UpgradeGiftZhct {function getInfoBYAIID($id){return null;}}
class UpgradeGiftBalanceLog {static $events=[];static function add(...$args){self::$events[]=$args;}}
class_alias(UpgradeGiftOrder::class,'app\\api\\model\\recharge\\Order');
class_alias(UpgradeGiftGuard::class,'app\\common\\service\\onecard\\UserGuard');
class_alias(UpgradeGiftZhct::class,'app\\common\\model\\zhct\\User');
class_alias(UpgradeGiftBalanceLog::class,'app\\api\\model\\user\\BalanceLog');
$app=new \think\App();$app->initialize();
\think\facade\Config::set(['default'=>'fixture','connections'=>['fixture'=>['type'=>'sqlite','database'=>tempnam(sys_get_temp_dir(),'upgrade-gift-'),'prefix'=>'','deploy'=>0,'break_reconnect'=>false,'trigger_sql'=>false]]],'database');
use think\facade\Db;
Db::execute('CREATE TABLE user (user_id INTEGER,store_id INTEGER,is_delete INTEGER,balance TEXT,gift_balance TEXT,update_time INTEGER)');
Db::execute('CREATE TABLE user_gift_log (user_id INTEGER,scene INTEGER,money TEXT,balance_before TEXT,balance_after TEXT,biz_type TEXT,biz_order_id INTEGER,biz_order_no TEXT,idempotency_key TEXT,describe TEXT,remark TEXT,operator_id TEXT,operator_name TEXT,store_id INTEGER,create_time DATETIME)');
require __DIR__.'/upgrade-baseline/AccountSettlementService.php';
require __DIR__.'/upgrade-baseline/PaySuccess.php';
$checks=0;
function giftCheck($ok,$message){$GLOBALS['checks']++;if(!$ok)throw new RuntimeException($message);}
function resetGiftFixture(){Db::name('user')->delete(true);Db::name('user_gift_log')->delete(true);Db::name('user')->insert(['user_id'=>7,'store_id'=>10001,'is_delete'=>0,'balance'=>'100.00','gift_balance'=>'20.00','update_time'=>0]);UpgradeGiftBalanceLog::$events=[];}
function privateCall($object,$method,$args=[]){$m=new ReflectionMethod($object,$method);$m->setAccessible(true);return $m->invokeArgs($object,$args);}
function property($object,$name,$value){$p=new ReflectionProperty($object,$name);$p->setAccessible(true);$p->setValue($object,$value);}
foreach(['consume','recharge'] as $scene){
 $versions=[];
 foreach(['old','new'] as $version){
  resetGiftFixture();
  if($scene==='consume'){
   $class='app\\common\\service\\account\\AccountSettlementService'.($version==='old'?'UpgradeBaseline':'');
   $service=new $class();
   privateCall($service,'deductCashAndGift',[Db::name('user')->where('user_id',7)->find(),['cash'=>'3.00','gift'=>'4.50'],7,8,'TEST-CONSUME',10001]);
   $user=Db::name('user')->where('user_id',7)->find();giftCheck((float)$user['balance']===97.0 && (float)$user['gift_balance']===15.5,'consume amounts');
  } else {
   $class='app\\api\\service\\recharge\\PaySuccess'.($version==='old'?'UpgradeBaseline':'');
   $service=(new ReflectionClass($class))->newInstanceWithoutConstructor();
   UpgradeGiftOrder::$current=new UpgradeGiftOrder(['order_id'=>8,'order_no'=>'TEST-RECHARGE','user_id'=>7,'store_id'=>10001,'pay_status'=>10,'pay_price'=>'8.00','gift_money'=>'2.50','gift_rule_id'=>0,'create_by'=>'fixture']);
   $service->orderInfo=UpgradeGiftOrder::$current;property($service,'orderNo','TEST-RECHARGE');property($service,'method','cash');property($service,'tradeId',0);
   privateCall($service,'updatePayStatus');
   $user=Db::name('user')->where('user_id',7)->find();giftCheck((float)$user['balance']===108.0 && (float)$user['gift_balance']===22.5,'recharge amounts');
   giftCheck(UpgradeGiftOrder::$current['pay_status']===20,'recharge completion');
   privateCall($service,'updatePayStatus');
   giftCheck(Db::name('user_gift_log')->count()===1,'recharge duplicate must not double gift');
  }
  $log=Db::name('user_gift_log')->where('user_id',7)->find();giftCheck($log['biz_type']===$scene,'ledger scene');
  if($version==='new')giftCheck((bool)preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/',(string)$log['create_time']),'target DATETIME format');
  else giftCheck(ctype_digit((string)$log['create_time']),'baseline used unix timestamp');
  unset($log['create_time'],$user['update_time']);$versions[$version]=[$log,$user,UpgradeGiftBalanceLog::$events];
 }
 giftCheck($versions['old']===$versions['new'],$scene.' all non-time ledger, amounts, cash log arguments unchanged');
}
echo "PASS gift dynamic: $checks assertions; real old/new methods and SQLite ledger, external boundaries replaced\n";
