<?php
require __DIR__.'/_bootstrap.php';

use Zoo\Database;
use Zoo\Auth\PlayerAuthService;
use Zoo\Wallet\WalletQuery;

try{
    $db=Database::connect();
    $player=(new PlayerAuthService($db))->authenticate([]);
    $uid=(int)$player['user_id'];

    $limit=max(20,min(200,(int)($_GET['limit']??100)));

    /*
     * Player Deposits are used as the canonical deposit timeline so pending,
     * confirmed, rejected and cancelled deposits are visible. Their matching
     * wallet_ledger deposit-confirmation row is excluded later to avoid a
     * duplicate transaction.
     */
    $q=$db->prepare("
      SELECT id,reference,method,amount,status,
             principal_credit,deposit_bonus,welcome_bonus,total_credit,
             confirmed_at,created_at,updated_at
      FROM player_deposits
      WHERE user_id=?
      ORDER BY id DESC
      LIMIT {$limit}
    ");
    $q->execute([$uid]);
    $deposits=[];
    $depositIds=[];
    foreach($q->fetchAll(PDO::FETCH_ASSOC) as $r){
        $depositIds[(string)$r['id']]=true;
        $deposits[]=[
            'key'=>'deposit:'.$r['id'],
            'category'=>'deposit',
            'kind'=>'deposit',
            'title'=>'Deposit',
            'method'=>$r['method'],
            'amount'=>(float)$r['amount'],
            'impact'=>(float)($r['total_credit']?:0),
            'status'=>$r['status'],
            'reference'=>$r['reference'],
            'principal_credit'=>(float)$r['principal_credit'],
            'deposit_bonus'=>(float)$r['deposit_bonus'],
            'welcome_bonus'=>(float)$r['welcome_bonus'],
            'total_credit'=>(float)$r['total_credit'],
            'created_at'=>$r['created_at'],
            'effective_at'=>$r['confirmed_at']?:$r['created_at']
        ];
    }

    /*
     * Withdrawals are canonical here as well, because the withdrawal table
     * contains the live processing status. Matching ledger reserve rows are
     * excluded later.
     */
    $q=$db->prepare("
      SELECT id,method,amount,status,provider_txn_id,admin_note,
             created_at,reviewed_at,processed_at
      FROM withdrawals
      WHERE user_id=?
      ORDER BY id DESC
      LIMIT {$limit}
    ");
    $q->execute([$uid]);
    $withdrawals=[];
    $withdrawalIds=[];
    foreach($q->fetchAll(PDO::FETCH_ASSOC) as $r){
        $withdrawalIds[(string)$r['id']]=true;
        $withdrawals[]=[
            'key'=>'withdrawal:'.$r['id'],
            'category'=>'withdrawal',
            'kind'=>'withdrawal',
            'title'=>'Withdrawal',
            'method'=>$r['method'],
            'amount'=>(float)$r['amount'],
            'impact'=>-(float)$r['amount'],
            'status'=>$r['status'],
            'reference'=>'#'.$r['id'],
            'provider_txn_id'=>$r['provider_txn_id'],
            'admin_note'=>$r['admin_note'],
            'created_at'=>$r['created_at'],
            'effective_at'=>$r['processed_at']?:($r['reviewed_at']?:$r['created_at'])
        ];
    }

    /*
     * Ledger is the source of truth for rewards and gameplay balance movements.
     * We intentionally omit canonical deposit / withdrawal rows already shown
     * above so the player never sees duplicate entries.
     */
    $q=$db->prepare("
      SELECT id,type,amount,cash_delta,bonus_delta,withdrawable_delta,
             reference_type,reference_id,metadata,created_at
      FROM wallet_ledger
      WHERE user_id=?
      ORDER BY id DESC
      LIMIT {$limit}
    ");
    $q->execute([$uid]);

    $ledger=[];
    foreach($q->fetchAll(PDO::FETCH_ASSOC) as $r){
        $refType=(string)($r['reference_type']??'');
        $refId=(string)($r['reference_id']??'');

        if($refType==='deposit' && isset($depositIds[$refId])) continue;
        if($refType==='withdrawal' && isset($withdrawalIds[$refId])) continue;

        $meta=[];
        if(!empty($r['metadata'])){
            $decoded=json_decode($r['metadata'],true);
            if(is_array($decoded))$meta=$decoded;
        }

        $type=(string)$r['type'];
        $category='other';
        $title='Balance activity';

        if($type==='bet'){
            $category='game';
            $title='Zoo Roulette bet';
        }elseif($type==='win'){
            $category='game';
            $title='Zoo Roulette win';
        }elseif($type==='refund'){
            $category='game';
            $title='Bet refund';
        }elseif(in_array($type,['reward','deposit_bonus','welcome_bonus'],true)){
            $category='reward';
            $rewardType=(string)($meta['reward_type']??$refType);
            $title=match($rewardType){
                'daily_checkin'=>'Daily Check-In',
                'vip_minute_gift'=>'VIP Minute Gift',
                'phone_binding_bonus'=>'Account Binding Bonus',
                'deposit_bonus'=>'Deposit Bonus',
                'welcome_bonus'=>'Welcome Bonus',
                default=>match($type){
                    'deposit_bonus'=>'Deposit Bonus',
                    'welcome_bonus'=>'Welcome Bonus',
                    default=>'Reward'
                }
            };
        }elseif($type==='adjustment'){
            // Older deposit confirmation implementations may use adjustment.
            if(($meta['kind']??'')==='deposit_confirmation'){
                continue;
            }
            $category='other';
            $title='Balance adjustment';
        }elseif($type==='deposit'){
            $category='deposit';
            $title='Deposit credit';
        }elseif($type==='withdrawal'){
            $category='withdrawal';
            $title='Withdrawal';
        }

        $impact=(float)$r['cash_delta']+(float)$r['bonus_delta'];

        $ledger[]=[
            'key'=>'ledger:'.$r['id'],
            'category'=>$category,
            'kind'=>$type,
            'title'=>$title,
            'amount'=>(float)$r['amount'],
            'impact'=>$impact,
            'cash_delta'=>(float)$r['cash_delta'],
            'bonus_delta'=>(float)$r['bonus_delta'],
            'withdrawable_delta'=>(float)$r['withdrawable_delta'],
            'status'=>'completed',
            'reference_type'=>$refType,
            'reference_id'=>$refId,
            'metadata'=>$meta,
            'created_at'=>$r['created_at'],
            'effective_at'=>$r['created_at']
        ];
    }

    $items=array_merge($deposits,$withdrawals,$ledger);
    usort($items,function($a,$b){
        $ta=strtotime($a['effective_at']??$a['created_at']??'1970-01-01');
        $tb=strtotime($b['effective_at']??$b['created_at']??'1970-01-01');
        if($ta===$tb)return strcmp($b['key'],$a['key']);
        return $tb<=>$ta;
    });
    $items=array_slice($items,0,$limit);

    $summary=[
        'all'=>count($items),
        'deposit'=>0,
        'withdrawal'=>0,
        'reward'=>0,
        'game'=>0,
        'other'=>0
    ];
    foreach($items as $i){
        $c=$i['category']??'other';
        if(isset($summary[$c]))$summary[$c]++;
    }

    json_out([
      'ok'=>true,
      'auth_mode'=>$player['auth_mode']??'registered',
      'wallet'=>(new WalletQuery($db))->get($uid),
      'summary'=>$summary,
      'transactions'=>$items
    ]);
}catch(Throwable $e){
    json_out(['ok'=>false,'error'=>$e->getMessage()],422);
}
