<?php
declare(strict_types=1);
require_once __DIR__ . '/_init.php';
rx_cron_boot('commerce',120);
$root=dirname(__DIR__);
if(!rx_cron_require_or_skip('commerce',[$root.'/config.php',$root.'/botapi.php',$root.'/pasarguard.php',$root.'/lib/Commerce/Commerce.php']))exit;
if(!rx_cron_db_ready('commerce'))exit;
$pdo=$GLOBALS['pdo']??null;if(!($pdo instanceof PDO))exit;
$commerce=$GLOBALS['itzCommerce']??new \iTz\Commerce\Commerce($pdo,$root);

$jobs=$pdo->query("SELECT * FROM itz_store_jobs WHERE status_name='queued' AND available_at<=UNIX_TIMESTAMP() ORDER BY id ASC LIMIT 10")->fetchAll(PDO::FETCH_ASSOC)?:[];
foreach($jobs as $job){
    $jid=(int)$job['id'];$oid=(int)$job['order_id'];
    try{
        $pdo->prepare("UPDATE itz_store_jobs SET status_name='running',attempts=attempts+1,updated_at=:t WHERE id=:id AND status_name='queued'")->execute([':t'=>time(),':id'=>$jid]);
        $order=$commerce->order($oid);if(!$order)throw new RuntimeException('Order not found');
        $type=(string)($order['fulfillment_type']??'manual');
        $result=['type'=>$type];
        if($type==='manual' || $type==='core' || $type==='webhook' || $type==='stock'){
            // Safe default: leave actions that need a human/core adapter for the admin queue.
            $pdo->prepare("UPDATE itz_store_jobs SET status_name='manual_pending',result_json=:r,updated_at=:t WHERE id=:id")->execute([':r'=>json_encode(['reason'=>'manual_or_adapter_required','type'=>$type],JSON_UNESCAPED_UNICODE),':t'=>time(),':id'=>$jid]);
            if(function_exists('itz_event'))itz_event('commerce.fulfillment.manual',['order_id'=>$oid,'type'=>$type]);
            continue;
        }
        if($type==='api' && (string)($order['backend_type']??'')==='pasarguard_reseller'){
            $ref=trim((string)($order['backend_ref']??''));
            if($ref==='')throw new RuntimeException('PasarGuard backend_ref is empty');
            $s=$pdo->prepare("SELECT * FROM marzban_panel WHERE type='pasarguard' AND (code_panel=:code_ref OR name_panel=:name_ref) LIMIT 1");$s->execute([':code_ref'=>$ref,':name_ref'=>$ref]);$panel=$s->fetch(PDO::FETCH_ASSOC);if(!$panel)throw new RuntimeException('PasarGuard backend not found');
            $params=json_decode((string)($order['parameters_json']??'{}'),true);if(!is_array($params))$params=[];
            $username=trim((string)($params['username']??$params['reseller_username']??''));
            if($username==='')throw new RuntimeException('Required parameter username is missing');
            $cfg=json_decode((string)($order['fulfillment_config_json']??'{}'),true);if(!is_array($cfg))$cfg=[];
            $password=pg_random_password((int)($cfg['password_length']??18));
            $options=['role_id'=>(int)($cfg['pg_role_id']??0),'data_limit'=>(int)($cfg['pg_data_limit']??0),'note'=>'Created by iTz Commerce order '.$order['public_id']];
            $res=pg_create_reseller_admin($panel,$username,$password,$options);
            if(empty($res['ok']))throw new RuntimeException((string)($res['error']??'PasarGuard reseller creation failed'));
            $admin=$res['admin']??[];$remoteId=(int)($admin['id']??$admin['admin_id']??0);
            $result=['type'=>'pasarguard_reseller','username'=>$username,'password'=>$password,'remote_admin_id'=>$remoteId,'panel_url'=>(string)($panel['url_panel']??'')];
            $pdo->prepare("UPDATE itz_store_jobs SET status_name='completed',result_json=:r,updated_at=:t WHERE id=:id")->execute([':r'=>$commerce->encrypt(json_encode($result,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)),':t'=>time(),':id'=>$jid]);
            try{$ins=$pdo->prepare("INSERT INTO pasarguard_resellers(invoice_id,user_id,panel_code,product_code,remote_admin_id,remote_username,status,expires_at,created_at,updated_at) VALUES(:inv,:uid,:panel,:prod,:rid,:user,'active',0,:created_at,:updated_at)");$ins->execute([':inv'=>$order['public_id'],':uid'=>$order['telegram_id']??null,':panel'=>$panel['code_panel']??$panel['name_panel'],':prod'=>$order['product_id']??null,':rid'=>$remoteId,':user'=>$username,':created_at'=>time(),':updated_at'=>time()]);}catch(Throwable $e){}
            $commerce->setOrderStatus($oid,'completed','commerce_worker');
            $chat=trim((string)($order['telegram_id']??''));
            if($chat!=='' && function_exists('telegram')){
                $txt="🛡 <b>نمایندگی PasarGuard آماده شد</b>\n\n👤 Username: <code>".htmlspecialchars($username,ENT_QUOTES,'UTF-8')."</code>\n🔑 Password: <code>".htmlspecialchars($password,ENT_QUOTES,'UTF-8')."</code>";
                if(!empty($panel['url_panel']))$txt.="\n🌐 Panel: ".htmlspecialchars((string)$panel['url_panel'],ENT_QUOTES,'UTF-8');
                telegram('sendMessage',['chat_id'=>$chat,'text'=>$txt,'parse_mode'=>'HTML']);
            }
            if(function_exists('itz_event'))itz_event('commerce.fulfillment.completed',['order_id'=>$oid,'type'=>'pasarguard_reseller']);
            continue;
        }
        $pdo->prepare("UPDATE itz_store_jobs SET status_name='manual_pending',result_json=:r,updated_at=:t WHERE id=:id")->execute([':r'=>json_encode(['reason'=>'unsupported_api_adapter','backend_type'=>$order['backend_type']??''],JSON_UNESCAPED_UNICODE),':t'=>time(),':id'=>$jid]);
    }catch(Throwable $e){
        $attempts=(int)($job['attempts']??0)+1;$next=time()+min(3600,60*(2**min(5,$attempts)));
        $status=$attempts>=5?'failed':'queued';
        $pdo->prepare('UPDATE itz_store_jobs SET status_name=:s,last_error=:e,available_at=:a,updated_at=:t WHERE id=:id')->execute([':s'=>$status,':e'=>substr($e->getMessage(),0,2000),':a'=>$next,':t'=>time(),':id'=>$jid]);
        if(function_exists('itz_event'))itz_event('commerce.fulfillment.error',['order_id'=>$oid,'error'=>$e->getMessage()]);
    }
}
echo "OK commerce jobs=".count($jobs)."\n";
