<?php
/**
 * Buy with card payment (submit receipt)
 */
require_once 'config.php';
if (function_exists('getSetting') && getSetting('sales_enabled','1') !== '1') {
    echo json_encode(['ok'=>false,'error'=>'فروش موقتاً متوقف است. لطفاً چند ساعت دیگر دوباره تلاش کنید.'], JSON_UNESCAPED_UNICODE);
    exit;
}
require_once 'manual_crypto_lib.php';
require_once 'discount_engine.php';
require_once 'plan_price_helper.php';
header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['ok' => false, 'error' => 'POST required'], JSON_UNESCAPED_UNICODE);
    exit;
}

$userId = (int)($_POST['user_id'] ?? 0);
$planId = (int)($_POST['plan_id'] ?? 0);
$receiptText = trim((string)($_POST['receipt_text'] ?? ''));
$discountCode = gemacc_normalize_discount_code($_POST['discount_code'] ?? '');
$requestId = trim((string)($_POST['request_id'] ?? ''));
$clientPayableAmount = (int)($_POST['payable_amount'] ?? 0);
$clientPayableRial = (int)($_POST['payable_rial'] ?? 0);
$useWalletCredit = (int)($_POST['use_wallet_credit'] ?? 0) === 1;

if (!$userId || !$planId) {
    echo json_encode(['ok' => false, 'error' => 'user_id and plan_id required'], JSON_UNESCAPED_UNICODE);
    exit;
}
manual_crypto_blocked_guard($userId);

try {
    $dupe = gemacc_idempotency_begin($pdo, $userId, $requestId, 'card_order');
    if ($dupe) {
        $cached = json_decode((string)($dupe['response_json'] ?? ''), true);
        if (is_array($cached) && !empty($cached)) {
            echo json_encode($cached, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit;
        }
        echo json_encode(['ok'=>false,'error'=>'این رسید قبلاً در حال ثبت است. چند ثانیه دیگر سفارش‌ها را بررسی کنید.'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    // Check force join membership
    if (getSetting('force_join_enabled', '0') === '1') {
        $stmt = $pdo->query("SELECT * FROM forced_channels WHERE is_active = 1");
        $channels = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $missingChannels = [];
        foreach ($channels as $channel) {
            $result = tg('getChatMember', ['chat_id' => $channel['channel_username'], 'user_id' => $userId]);
            if (!$result || empty($result['ok'])) continue;
            $status = $result['result']['status'] ?? '';
            if (!in_array($status, ['member', 'administrator', 'creator', 'restricted'], true)) $missingChannels[] = $channel;
        }
        if ($missingChannels) {
            echo json_encode(['ok'=>false,'error'=>'ابتدا باید در کانال‌های زیر عضو شوید','force_join'=>true,'missing_channels'=>$missingChannels], JSON_UNESCAPED_UNICODE);
            exit;
        }
    }

    $stmt = $pdo->prepare("SELECT p.*, pc.service_type AS category_service_type, pc.traffic_type AS category_traffic_type, pc.traffic_limit_gb AS category_traffic_limit_gb, pc.months AS category_months FROM plans p LEFT JOIN plan_categories pc ON pc.id=p.category_id WHERE p.id = ? AND p.is_active = 1");
    $stmt->execute([$planId]);
    $plan = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$plan) throw new RuntimeException('پلن یافت نشد');

    $originalPrice = gemacc_plan_effective_sale_price($plan);
    $discount = ['valid'=>false,'discount_amount'=>0,'final_price'=>$originalPrice];
    if ($discountCode !== '') {
        $discount = gemacc_discount_preview($pdo, $userId, $discountCode, $originalPrice, $planId, 'card');
        if (empty($discount['valid'])) throw new RuntimeException($discount['message'] ?? 'کد تخفیف نامعتبر است');
    }
    $finalPriceBeforeWallet = max(0, (int)($discount['final_price'] ?? $originalPrice));
    $walletApplied = 0;
    $preWalletApplied = 0;
    if ($useWalletCredit && $finalPriceBeforeWallet > 0) {
        try { $q=$pdo->prepare("SELECT balance FROM users WHERE id=?"); $q->execute([$userId]); $preWalletApplied = min(max(0,(int)$q->fetchColumn()), $finalPriceBeforeWallet); } catch (Throwable $ignored) {}
    }
    $finalPrice = max(0, $finalPriceBeforeWallet - $preWalletApplied);
    if ($useWalletCredit && $finalPrice <= 0) throw new RuntimeException('موجودی کیف پول کل مبلغ را پوشش می‌دهد؛ لطفاً پرداخت کامل از کیف پول را انتخاب کنید.');
    $trafficTypeForTolerance = $plan['traffic_type'] ?: ($plan['category_traffic_type'] ?? 'unlimited');
    $tolerance = function_exists('gemaccPaymentToleranceToman') ? gemaccPaymentToleranceToman(['traffic_type'=>$trafficTypeForTolerance]) : ($trafficTypeForTolerance === 'limited' ? 30000 : 50000);
    $payablePrice = $finalPrice;
    $payableRial = $finalPrice * 10;
    if ($clientPayableRial > 0) {
        $minAllowedRial = $finalPrice * 10;
        $maxAllowedRial = ($finalPrice + $tolerance) * 10;
        if ($clientPayableRial < $minAllowedRial || $clientPayableRial > $maxAllowedRial) {
            throw new RuntimeException('مبلغ واریزی معتبر نیست. لطفاً دقیقاً مبلغ ریالی نمایش‌داده‌شده در صفحه پرداخت را واریز کنید.');
        }
        $payableRial = $clientPayableRial;
        $payablePrice = (int)ceil($clientPayableRial / 10);
    } elseif ($clientPayableAmount > 0) {
        if ($clientPayableAmount < $finalPrice || $clientPayableAmount > ($finalPrice + $tolerance)) {
            throw new RuntimeException('مبلغ واریزی معتبر نیست. لطفاً دقیقاً مبلغ نمایش‌داده‌شده در صفحه پرداخت را واریز کنید.');
        }
        $payablePrice = $clientPayableAmount;
        $payableRial = $clientPayableAmount * 10;
    }

    $receiptFileId = null;
    $uploadDir = __DIR__ . '/../uploads/';
    if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);

    if (isset($_FILES['receipt']) && $_FILES['receipt']['error'] === UPLOAD_ERR_OK) {
        if ((int)($_FILES['receipt']['size'] ?? 0) > 5 * 1024 * 1024) throw new RuntimeException('حجم رسید نباید بیشتر از ۵ مگابایت باشد');
        $tmpName = $_FILES['receipt']['tmp_name'];
        $ext = strtolower(pathinfo($_FILES['receipt']['name'], PATHINFO_EXTENSION));
        $allowed = ['jpg'=>'image/jpeg','jpeg'=>'image/jpeg','png'=>'image/png','webp'=>'image/webp'];
        if (!isset($allowed[$ext])) throw new RuntimeException('فقط فایل‌های jpg، png و webp مجاز هستند');
        $finfo = function_exists('finfo_open') ? finfo_open(FILEINFO_MIME_TYPE) : null;
        $mime = $finfo ? finfo_file($finfo, $tmpName) : ($_FILES['receipt']['type'] ?? '');
        if ($finfo) finfo_close($finfo);
        if (!in_array($mime, array_values($allowed), true) || !@getimagesize($tmpName)) throw new RuntimeException('فایل رسید تصویر معتبر نیست');
        $fileName = 'receipt_' . $userId . '_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
        if (!move_uploaded_file($tmpName, $uploadDir . $fileName)) throw new RuntimeException('ذخیره رسید ناموفق بود');
        $receiptFileId = $fileName;
    }
    if (!$receiptFileId && $receiptText === '') throw new RuntimeException('تصویر رسید یا رسید متنی/شماره پیگیری الزامی است');

    $trafficType = $plan['traffic_type'] ?: ($plan['category_traffic_type'] ?? 'unlimited');
    $trafficLimitGb = $trafficType === 'limited' ? ($plan['traffic_limit_gb'] ?? $plan['category_traffic_limit_gb'] ?? null) : null;
    $rawSvc = strtolower((string)($plan['protocol'] ?? $plan['category_service_type'] ?? 'openvpn_l2tp')); $serviceType = in_array($rawSvc, ['windscribe','expressvpn','v2ray'], true) ? $rawSvc : 'openvpn_l2tp';

    $pdo->beginTransaction();
    if ($useWalletCredit && $finalPriceBeforeWallet > 0) {
        $bst = $pdo->prepare("SELECT balance FROM users WHERE id=? FOR UPDATE");
        $bst->execute([$userId]);
        $balanceNow = max(0, (int)$bst->fetchColumn());
        $walletApplied = min($balanceNow, $finalPriceBeforeWallet);
        if ($walletApplied > 0) {
            $pdo->prepare("UPDATE users SET balance=balance-? WHERE id=? AND balance>=?")->execute([$walletApplied, $userId, $walletApplied]);
            $pdo->prepare("INSERT INTO wallet_transactions (user_id, amount, type, status, description) VALUES (?, ?, 'PURCHASE', 'COMPLETED', ?)")->execute([$userId, $walletApplied, 'کسر موجودی کیف پول برای سفارش کارت به کارت']);
            $finalPrice = max(0, $finalPriceBeforeWallet - $walletApplied);
            // Recalculate payable display using the client-provided exact amount for the remaining amount.
            if ($clientPayableRial <= 0 && $clientPayableAmount <= 0) { $payablePrice = $finalPrice; $payableRial = $finalPrice * 10; }
        }
    }
    $meta = json_encode(['request_id'=>$requestId,'original_price'=>$originalPrice,'discount_code'=>$discountCode,'discount_amount'=>(int)($discount['discount_amount'] ?? 0),'final_price_before_wallet'=>$finalPriceBeforeWallet,'wallet_credit_used'=>$walletApplied,'final_price'=>$finalPrice,'payable_price'=>$payablePrice,'payable_rial'=>$payableRial,'payment_tolerance'=>$tolerance,'note'=>$receiptText], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    $stmt = $pdo->prepare("INSERT INTO orders (user_id, plan_id, category_id, plan_code, plan_title, service_type, duration, months, requested_seats, traffic_type, traffic_limit_gb, price, purchase_price, payment_method, payment_status, delivery_status, status, receipt_file_id, receipt_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'CARD', 'pending', 'pending', 'PENDING', ?, ?)");
    $stmt->execute([$userId, $planId, $plan['category_id'] ?? null, $plan['code'] ?? null, $plan['title'] ?? 'OpenVPN | L2TP', $serviceType, $plan['duration'], (int)($plan['months'] ?? $plan['category_months'] ?? 1), max(1,(int)($plan['seats'] ?? $plan['user_count'] ?? 1)), $trafficType, $trafficLimitGb, $payablePrice, gemacc_plan_effective_purchase_price($plan), $receiptFileId, $meta]);
    $orderId = (int)$pdo->lastInsertId();
    gemacc_discount_apply($pdo, $discount, $userId, $orderId);
    $response = ['ok'=>true,'message'=>'سفارش ثبت شد. پس از تأیید ادمین، اشتراک ارسال می‌شود.','data'=>['order_id'=>$orderId],'order_id'=>$orderId,'original_price'=>$originalPrice,'discount_amount'=>(int)($discount['discount_amount'] ?? 0),'final_price'=>$finalPrice,'wallet_credit_used'=>$walletApplied,'payable_price'=>$payablePrice,'payable_rial'=>$payableRial];
    gemacc_idempotency_finish($pdo, $userId, $requestId, 'card_order', $orderId, $response);
    $pdo->commit();

    $stmt = $pdo->prepare("SELECT first_name, username FROM users WHERE id = ?");
    $stmt->execute([$userId]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
    $userName = $user['first_name'] ?? $user['username'] ?? 'کاربر';

    $adminMsg = "🛒 **سفارش جدید (مینی‌اپ)**\n\n" .
        "👤 {$userName}\n" .
        "🆔 {$userId}\n" .
        "📦 پلن: {$plan['title']}\n" .
        "💵 مبلغ قابل واریز: " . money($payablePrice) . "\n" .
        "🔢 مبلغ دقیق ریالی: `" . number_format($payableRial, 0, '.', '') . "` ریال\n" .
        ($payablePrice !== $finalPrice ? "💳 قیمت اصلی/بعد تخفیف: " . money($finalPrice) . "\n" : '') .
        ((int)($discount['discount_amount'] ?? 0) > 0 ? "🎫 تخفیف: " . money((int)$discount['discount_amount']) . " ({$discountCode})\n" : '') .
        ($walletApplied > 0 ? "💎 کسر از کیف پول: " . money($walletApplied) . "\n" : '') .
        "🆔 سفارش: #{$orderId}";
    if ($receiptText) $adminMsg .= "\n\n📝 توضیحات:\n{$receiptText}";

    $adminButtons = ['inline_keyboard' => [
        [['text'=>'✅ تأیید','callback_data'=>"ADMIN_APPROVE_ORDER__{$orderId}"], ['text'=>'❌ رد','callback_data'=>"ADMIN_REJECT_ORDER__{$orderId}"]],
        [['text'=>'⚠️ اخطار فیش فیک','callback_data'=>"ADMIN_FAKE_RECEIPT_ORDER__{$orderId}"]],
    ]];
    $admins = array_filter(array_map('trim', explode(',', ADMIN_IDS)));
    $filePath = $uploadDir . $receiptFileId;
    $uploadedFileId = null;
    foreach ($admins as $adminId) {
        if ($receiptFileId && file_exists($filePath)) {
            if ($uploadedFileId === null && class_exists('CURLFile')) {
                $ch = curl_init();
                curl_setopt_array($ch, [CURLOPT_URL=>"https://api.telegram.org/bot" . BOT_TOKEN . "/sendPhoto", CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>['chat_id'=>$adminId,'photo'=>new CURLFile($filePath),'caption'=>$adminMsg,'parse_mode'=>'Markdown','reply_markup'=>json_encode($adminButtons, JSON_UNESCAPED_UNICODE)]]);
                $result = json_decode((string)curl_exec($ch), true);
                curl_close($ch);
                if ($result && !empty($result['ok'])) $uploadedFileId = $result['result']['photo'][0]['file_id'] ?? null;
            } elseif ($uploadedFileId) {
                tg('sendPhoto', ['chat_id'=>$adminId,'photo'=>$uploadedFileId,'caption'=>$adminMsg,'parse_mode'=>'Markdown','reply_markup'=>json_encode($adminButtons, JSON_UNESCAPED_UNICODE)]);
            } else {
                tg('sendMessage', ['chat_id'=>$adminId,'text'=>$adminMsg,'parse_mode'=>'Markdown','reply_markup'=>json_encode($adminButtons, JSON_UNESCAPED_UNICODE)]);
            }
        } else {
            tg('sendMessage', ['chat_id'=>$adminId,'text'=>$adminMsg . "\n\n📝 این سفارش با رسید متنی ثبت شده است.",'parse_mode'=>'Markdown','reply_markup'=>json_encode($adminButtons, JSON_UNESCAPED_UNICODE)]);
        }
    }
    echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    if (!empty($receiptFileId ?? null) && file_exists(($uploadDir ?? '') . $receiptFileId)) @unlink($uploadDir . $receiptFileId);
    $response = ['ok'=>false,'error'=>$e->getMessage()];
    if ($requestId !== '') { try { gemacc_idempotency_finish($pdo, $userId, $requestId, 'card_order', null, $response); } catch (Throwable $ignored) {} }
    echo json_encode($response, JSON_UNESCAPED_UNICODE);
}
