<?php
// User/admin order cancellation service with SQL logging and safer refund handling.

if(!function_exists('bot_order_cancel_settings')){
    function bot_order_cancel_settings(){
        $d = ['Condition'=>'✅فعال','mincancell'=>1,'timecancell'=>10,'Coefficientadscoin'=>0.5];
        $s = function_exists('bot_data_get_json') ? bot_data_get_json('lib/kodam/data-Cancellads.json', $d) : $d;
        if(!is_array($s)) $s = [];
        $s = array_merge($d, $s);
        $s['Condition'] = ((string)($s['Condition'] ?? '') === '❌غیر فعال') ? '❌غیر فعال' : '✅فعال';
        $s['mincancell'] = max(0, (int)($s['mincancell'] ?? 1));
        $s['timecancell'] = max(0, (int)($s['timecancell'] ?? 10));
        $coef = str_replace(',', '.', (string)($s['Coefficientadscoin'] ?? '0.5'));
        $s['Coefficientadscoin'] = is_numeric($coef) ? max(0, (float)$coef) : 0.5;
        return $s;
    }
}

if(!function_exists('bot_order_cancel_ensure_sql')){
    function bot_order_cancel_ensure_sql(){
        $pdo = function_exists('bot_sql_pdo') ? bot_sql_pdo() : null;
        if(!$pdo) return null;
        try{
            $pdo->exec("CREATE TABLE IF NOT EXISTS bot_order_cancel_actions (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                order_id VARCHAR(64) NOT NULL,
                owner_id VARCHAR(32) NULL,
                actor_id VARCHAR(32) NULL,
                cancel_type VARCHAR(30) NOT NULL DEFAULT 'user',
                refund_amount INT NOT NULL DEFAULT 0,
                remaining_count INT NOT NULL DEFAULT 0,
                reason VARCHAR(191) NULL,
                data_json LONGTEXT NULL,
                created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                KEY idx_order_cancel (order_id),
                KEY idx_owner_cancel (owner_id),
                KEY idx_actor_cancel (actor_id),
                KEY idx_created (created_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
        }catch(Throwable $e){
            error_log('BOT order cancel SQL install failed: '.$e->getMessage());
            return null;
        }
        return $pdo;
    }
}

if(!function_exists('bot_order_cancel_log')){
    function bot_order_cancel_log($orderId, $ownerId, $actorId, $type, $refund, $remaining, $reason, array $data=[]){
        $pdo = bot_order_cancel_ensure_sql();
        if(!$pdo) return false;
        try{
            $json = function_exists('bot_json_encode') ? bot_json_encode($data) : json_encode($data, JSON_UNESCAPED_UNICODE);
            $st = $pdo->prepare('INSERT INTO bot_order_cancel_actions (order_id, owner_id, actor_id, cancel_type, refund_amount, remaining_count, reason, data_json) VALUES (?,?,?,?,?,?,?,?)');
            $st->execute([(string)$orderId, (string)$ownerId, (string)$actorId, (string)$type, (int)$refund, (int)$remaining, (string)$reason, $json]);
            return true;
        }catch(Throwable $e){ error_log('BOT order cancel log failed: '.$e->getMessage()); }
        return false;
    }
}

if(!function_exists('bot_order_cancel_clean_id')){
    function bot_order_cancel_clean_id($raw){
        $raw = preg_replace('/[^A-Za-z0-9_\-]/', '', (string)$raw);
        if($raw !== '' && function_exists('bale_resolve_order_id_from_callback')) $raw = bale_resolve_order_id_from_callback($raw);
        return preg_replace('/[^A-Za-z0-9_\-]/', '', (string)$raw);
    }
}

if(!function_exists('bot_order_cancel_status_active')){
    function bot_order_cancel_status_active($order){
        $st = (string)($order['stats'] ?? $order['status'] ?? '');
        return $st === 'در حال اجرا ♻️' || in_array(strtolower($st), ['active','running','run','on','1'], true);
    }
}

if(!function_exists('bot_order_cancel_refund_amount')){
    function bot_order_cancel_refund_amount($order, array $settings){
        $target = max(0, (int)($order['member'] ?? $order['target_count'] ?? 0));
        $got = max(0, (int)($order['tedad'] ?? $order['received_count'] ?? 0));
        $remaining = max(0, $target - $got);
        $spent = max(0, (int)($order['Points'] ?? $order['points'] ?? 0));
        $coef = max(0, (float)($settings['Coefficientadscoin'] ?? 0));
        $refund = (int)floor($remaining * $coef);
        if($spent > 0) $refund = min($refund, $spent);
        return ['refund'=>max(0, $refund), 'remaining'=>$remaining, 'target'=>$target, 'got'=>$got, 'spent'=>$spent];
    }
}

if(!function_exists('bot_order_cancel_validate')){
    function bot_order_cancel_validate($orderId, $actorId, $isAdminAction=false){
        $settings = bot_order_cancel_settings();
        if(($settings['Condition'] ?? '✅فعال') !== '✅فعال') return ['ok'=>false, 'error'=>'disabled', 'settings'=>$settings];
        $orderId = bot_order_cancel_clean_id($orderId);
        if($orderId === '' || !bot_data_file_exists('ads/'.$orderId.'.json')) return ['ok'=>false, 'error'=>'not_found', 'order_id'=>$orderId, 'settings'=>$settings];
        $order = bot_data_get_json('ads/'.$orderId.'.json', []);
        if(!is_array($order) || !$order) return ['ok'=>false, 'error'=>'not_found', 'order_id'=>$orderId, 'settings'=>$settings];
        $ownerId = (string)($order['admin'] ?? $order['owner_id'] ?? '');
        if(!$isAdminAction && (string)$actorId !== $ownerId) return ['ok'=>false, 'error'=>'not_owner', 'order_id'=>$orderId, 'order'=>$order, 'settings'=>$settings];
        if(!bot_order_cancel_status_active($order)) return ['ok'=>false, 'error'=>'not_active', 'order_id'=>$orderId, 'order'=>$order, 'settings'=>$settings];
        $target = (int)($order['member'] ?? 0);
        if($target < (int)$settings['mincancell']) return ['ok'=>false, 'error'=>'under_min', 'order_id'=>$orderId, 'order'=>$order, 'settings'=>$settings];
        $created = (int)($order['time-cancell'] ?? $order['stamp'] ?? $order['created_ts'] ?? 0);
        $allowAt = $created + (int)$settings['timecancell'];
        if($created > 0 && time() < $allowAt) return ['ok'=>false, 'error'=>'too_early', 'remain_seconds'=>($allowAt - time()), 'order_id'=>$orderId, 'order'=>$order, 'settings'=>$settings];
        $calc = bot_order_cancel_refund_amount($order, $settings);
        return ['ok'=>true, 'order_id'=>$orderId, 'order'=>$order, 'settings'=>$settings, 'calc'=>$calc, 'owner_id'=>$ownerId];
    }
}

if(!function_exists('bot_order_cancel_error_text')){
    function bot_order_cancel_error_text($res, $money='الماس'){
        $s = $res['settings'] ?? bot_order_cancel_settings();
        $err = (string)($res['error'] ?? 'unknown');
        if($err === 'disabled') return '❌ لغو سفارش در حال حاضر غیرفعال است.';
        if($err === 'not_found') return '❌ سفارش یافت نشد یا کد پیگیری نامعتبر است.';
        if($err === 'not_owner') return '❌ این سفارش متعلق به شما نیست.';
        if($err === 'not_active') return '❌ این سفارش فعال نیست یا قبلاً لغو/تکمیل شده است.';
        if($err === 'under_min') return "❌ سفارش‌هایی که کمتر از **{$s['mincancell']}** ممبر باشند قابل لغو نیستند.";
        if($err === 'too_early'){
            $remainSeconds = max(1, (int)($res['remain_seconds'] ?? 0));
            if($remainSeconds < 60){
                $remainText = $remainSeconds . ' ثانیه';
            }else{
                $remainText = ((int)ceil($remainSeconds / 60)) . ' دقیقه';
            }
            return "⚠️ هنوز امکان لغو این سفارش فعال نشده است.

⏱ زمان باقی‌مانده: **{$remainText}**";
        }
        return '❌ لغو سفارش انجام نشد.';
    }
}

if(!function_exists('bot_order_cancel_execute')){
    function bot_order_cancel_execute($orderId, $actorId, $chatId, $messageId=null, $isAdminAction=false, $money='الماس'){
        global $chads;
        $res = bot_order_cancel_validate($orderId, $actorId, $isAdminAction);
        if(empty($res['ok'])) return $res;
        $orderId = $res['order_id'];
        $order = $res['order'];
        $ownerId = (string)($res['owner_id'] ?? ($order['admin'] ?? ''));
        $calc = $res['calc'];
        $refund = (int)$calc['refund'];
        $remaining = (int)$calc['remaining'];
        $deleteResult = null;
        if(!empty($order['postid']) && trim((string)$chads) !== ''){
            $deleteResult = bot('deletemessage', ['chat_id'=>'@'.trim((string)$chads), 'message_id'=>(string)$order['postid']]);
        }
        $order['stats'] = 'کنسل شده❌';
        $order['cancelled_at'] = time();
        $order['cancelled_by'] = (string)$actorId;
        $order['cancel_type'] = $isAdminAction ? 'admin' : 'user';
        $order['cancel_refund'] = $refund;
        if(function_exists('bot_cache_invalidate_for_path')) bot_cache_invalidate_for_path('ads/'.$orderId.'.json');
        bot_data_put_json('ads/'.$orderId.'.json', $order);

        $walletAfter = null;
        if($refund > 0 && $ownerId !== ''){
            if(function_exists('bot_wallet_add')){
                $wr = bot_wallet_add($ownerId, $refund, $isAdminAction ? 'order_admin_cancel_refund' : 'order_user_cancel_refund', ['order_id'=>$orderId, 'remaining'=>$remaining]);
                if(is_array($wr) && isset($wr['after'])) $walletAfter = (int)$wr['after'];
            }else{
                $u = bot_data_get_json('melat/'.$ownerId.'.json', []);
                if(is_array($u)){
                    $u['Points'] = max(0, (int)($u['Points'] ?? 0)) + $refund;
                    saveJson('melat/'.$ownerId.'.json', $u);
                    $walletAfter = (int)$u['Points'];
                }
            }
        }
        bot_order_cancel_log($orderId, $ownerId, $actorId, $isAdminAction ? 'admin' : 'user', $refund, $remaining, 'cancel_order', ['delete_result'=>$deleteResult, 'calc'=>$calc]);
        return ['ok'=>true, 'order_id'=>$orderId, 'order'=>$order, 'refund'=>$refund, 'remaining'=>$remaining, 'wallet_after'=>$walletAfter, 'delete_result'=>$deleteResult];
    }
}
