<?php
require_once 'manual_crypto_lib.php';
require_once 'plisio_lib.php';
require_once '_vpn_helpers.php';
require_once 'discount_engine.php';
require_once 'plan_price_helper.php';
header('Content-Type: application/json; charset=utf-8');

function crypto_json($data, int $code=200){ http_response_code($code); echo json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); exit; }
function crypto_plan_price_data(int $userId, int $planId, string $discountCode): array {
    global $pdo;
    $st = $pdo->prepare("SELECT p.*, pc.name AS category_name, pc.months AS category_months, pc.code AS category_code, pc.service_type AS category_service_type, pc.traffic_type AS category_traffic_type, pc.traffic_limit_gb AS category_traffic_limit_gb FROM plans p LEFT JOIN plan_categories pc ON pc.id=p.category_id WHERE p.id=? AND p.is_active=1 AND p.deleted_at IS NULL AND (p.category_id IS NULL OR (pc.id IS NOT NULL AND pc.is_active=1 AND pc.deleted_at IS NULL))");
    $st->execute([$planId]);
    $plan = $st->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, 'crypto');
        if (empty($discount['valid'])) throw new RuntimeException($discount['message'] ?? 'کد تخفیف نامعتبر است');
    }
    $price = max(0, (int)($discount['final_price'] ?? $originalPrice));
    $requestedSeats = max(1, (int)($plan['user_count'] ?? $plan['seats'] ?? 1));
    $months = max(1, (int)($plan['months'] ?? $plan['category_months'] ?? 1));
    $duration = (string)($plan['duration'] ?? $plan['category_code'] ?? ($months . 'M'));
    $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';
    return compact('plan','originalPrice','discount','price','requestedSeats','months','duration','trafficType','trafficLimitGb','serviceType');
}
function crypto_insert_order(array $d, int $userId, int $planId, string $method, string $meta, ?string $receiptFile=null, string $status='PENDING'): int {
    global $pdo;
    $p = $d['plan'];
    $orderStmt = $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, required_accounts, delivered_accounts, price, purchase_price, payment_method, payment_status, delivery_status, status, receipt_file_id, receipt_text) VALUES(?,?,?,?,?,?,?,?,?,?,?, ?,0,?,?,?,?,?,?,?,?)");
    $orderStmt->execute([$userId, $planId, $p['category_id'] ?? null, $p['code'] ?? ('PLAN-' . $planId), $p['title'] ?? 'OpenVPN | L2TP', $d['serviceType'] ?? 'openvpn_l2tp', $d['duration'], $d['months'], $d['requestedSeats'], $d['trafficType'], $d['trafficLimitGb'], $d['requestedSeats'], $d['price'], gemacc_plan_effective_purchase_price($p), $method, 'pending', 'pending', $status, $receiptFile, $meta]);
    $orderId = (int)$pdo->lastInsertId();
    if (!empty($d['discount']['valid'])) gemacc_discount_apply($pdo, $d['discount'], $userId, $orderId);
    return $orderId;
}

function crypto_wallet_preview(PDO $pdo, int $userId, int $amount, bool $useWallet): array {
    if (!$useWallet || $amount <= 0) return ['wallet_applied'=>0,'payable'=>$amount];
    try { $st=$pdo->prepare("SELECT balance FROM users WHERE id=?"); $st->execute([$userId]); $bal=max(0,(int)$st->fetchColumn()); } catch(Throwable $e) { $bal=0; }
    $applied=min($bal,$amount);
    return ['wallet_applied'=>$applied,'payable'=>max(0,$amount-$applied)];
}
function crypto_wallet_deduct_locked(PDO $pdo, int $userId, int $amount, bool $useWallet, string $desc): array {
    if (!$useWallet || $amount <= 0) return ['wallet_applied'=>0,'payable'=>$amount];
    $st=$pdo->prepare("SELECT balance FROM users WHERE id=? FOR UPDATE"); $st->execute([$userId]); $bal=max(0,(int)$st->fetchColumn());
    $applied=min($bal,$amount);
    if ($applied > 0) {
        $pdo->prepare("UPDATE users SET balance=balance-? WHERE id=? AND balance>=?")->execute([$applied,$userId,$applied]);
        $pdo->prepare("INSERT INTO wallet_transactions (user_id, amount, type, status, description) VALUES (?, ?, 'PURCHASE', 'COMPLETED', ?)")->execute([$userId,$applied,$desc]);
    }
    return ['wallet_applied'=>$applied,'payable'=>max(0,$amount-$applied)];
}

function crypto_asset_wallet_payload(array $cfg, string $asset): array {
    $asset = manual_crypto_normalize_asset($asset);
    if ($asset === '') $asset = 'USDT';
    if (!in_array($asset, $cfg['enabled_assets'], true)) throw new RuntimeException('این ارز در تنظیمات فعال نیست.');
    if ($asset === 'TRX') {
        if ($cfg['trx_address'] === '') throw new RuntimeException('آدرس ولت TRX تنظیم نشده است.');
        return ['asset'=>'TRX','label'=>'ترون TRX','address'=>$cfg['trx_address'],'network'=>$cfg['trx_network']];
    }
    if ($cfg['usdt_address'] === '') throw new RuntimeException('آدرس ولت USDT تنظیم نشده است.');
    return ['asset'=>'USDT','label'=>'تتر USDT','address'=>$cfg['usdt_address'],'network'=>$cfg['usdt_network']];
}
function crypto_public_assets(array $cfg, int $amount): array {
    $out=[];
    foreach ($cfg['enabled_assets'] as $asset) {
        try {
            $w=crypto_asset_wallet_payload($cfg,$asset);
            $w['quote']=manual_crypto_selected_quote($amount,$asset);
            $out[]=$w;
        } catch (Throwable $ignored) {}
    }
    return $out;
}

function crypto_send_user_gateway_link(int $userId, int $orderId, string $url, int $amount): void {
    $text = "⚡ پرداخت فوری ارز دیجیتال\n\nسفارش شما در مرحله پرداخت درگاه است.\n💰 مبلغ سفارش: " . money($amount) . "\n\nاگر می‌خواهید این مبلغ را در درگاه پرداخت کنید، روی لینک زیر بزنید. بعد از پرداخت موفق، سفارش خودکار تأیید و ارسال می‌شود.";
    tg('sendMessage', ['chat_id'=>$userId, 'text'=>$text, 'reply_markup'=>json_encode(['inline_keyboard'=>[[['text'=>'⚡ ورود به درگاه پرداخت', 'url'=>$url]]]], JSON_UNESCAPED_UNICODE)]);
}

try {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') crypto_json(['ok'=>false,'error'=>'POST required']);
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
    if (stripos($contentType, 'application/json') !== false) {
        $input = json_decode(file_get_contents('php://input'), true);
        if (!is_array($input)) $input = [];
    } else {
        $input = $_POST;
    }
    $userId = (int)($input['user_id'] ?? 0);
    $planId = (int)($input['plan_id'] ?? 0);
    $action = (string)($input['action'] ?? 'choose');
    $asset = manual_crypto_normalize_asset((string)($input['asset'] ?? ''));
    $useWalletCredit = (int)($input['use_wallet_credit'] ?? 0) === 1;
    if (!$userId || !$planId) crypto_json(['ok'=>false,'error'=>'user_id and plan_id required']);
    manual_crypto_blocked_guard($userId);
    $discountCode = function_exists('gemacc_normalize_discount_code') ? gemacc_normalize_discount_code($input['discount_code'] ?? '') : trim((string)($input['discount_code'] ?? ''));
    $d = crypto_plan_price_data($userId, $planId, $discountCode);

    if ($action === 'choose') {
        $cfg = manual_crypto_settings();
        $wp = crypto_wallet_preview($pdo, $userId, $d['price'], $useWalletCredit);
        $displayAmount = (int)$wp['payable'];
        if (!$cfg['enabled'] && !(function_exists('plisio_enabled') && plisio_enabled())) throw new RuntimeException('پرداخت ارز دیجیتال فعلاً غیرفعال است.');
        $assets = [];
        foreach (manual_crypto_enabled_assets() as $a) {
            $assets[] = [
                'asset'=>$a,
                'label'=>manual_crypto_asset_label($a),
                'network'=>$a === 'TRX' ? $cfg['trx_network'] : $cfg['usdt_network'],
                'quote'=>manual_crypto_selected_quote($displayAmount, $a),
                'manual_ready'=>$a === 'TRX' ? ($cfg['trx_address'] !== '') : ($cfg['usdt_address'] !== '')
            ];
        }
        crypto_json([
            'ok'=>true,
            'manual_available'=>$cfg['enabled'],
            'gateway_available'=>function_exists('plisio_enabled') && plisio_enabled(),
            'amount'=>$displayAmount,
            'wallet_credit_used'=>(int)$wp['wallet_applied'],
            'original_final_price'=>$d['price'],
            'assets'=>$assets,
            'quote'=>manual_crypto_quote($displayAmount)
        ]);
    }

    if ($action === 'manual_info') {
        $cfg = manual_crypto_require_enabled();
        if ($asset === '') throw new RuntimeException('لطفاً ابتدا ارز پرداخت را انتخاب کنید.');
        $w = crypto_asset_wallet_payload($cfg, $asset);
        $wp = crypto_wallet_preview($pdo, $userId, $d['price'], $useWalletCredit);
        $displayAmount = (int)$wp['payable'];
        crypto_json([
            'ok'=>true,
            'await_receipt'=>true,
            'manual_available'=>true,
            'gateway_available'=>function_exists('plisio_enabled') && plisio_enabled(),
            'message'=>'آدرس پرداخت آماده است. بعد از پرداخت، رسید را ارسال کنید.',
            'amount'=>$displayAmount,
            'wallet_credit_used'=>(int)$wp['wallet_applied'],
            'original_final_price'=>$d['price'],
            'asset'=>$w['asset'],
            'asset_label'=>$w['label'],
            'token'=>$w['asset'],
            'network'=>$w['network'],
            'wallets'=>[strtolower($w['asset'])=>['address'=>$w['address'],'network'=>$w['network']]],
            'selected_quote'=>manual_crypto_selected_quote($displayAmount, $w['asset']),
            'wallet_credit_used'=>(int)$wp['wallet_applied'],
            'original_final_price'=>$d['price'],
            'instructions'=>$cfg['help'],
            'quote'=>manual_crypto_quote($displayAmount)
        ]);
    }

    if ($action === 'gateway') {
        if (!function_exists('plisio_enabled') || !plisio_enabled()) throw new RuntimeException('درگاه Plisio فعال نیست یا API Key تنظیم نشده است.');
        if ($asset === '') throw new RuntimeException('لطفاً ابتدا ارز پرداخت را انتخاب کنید.');
        if (!in_array($asset, manual_crypto_enabled_assets(), true)) throw new RuntimeException('این ارز در تنظیمات فعال نیست.');
        $pdo->beginTransaction();
        $wp = crypto_wallet_deduct_locked($pdo, $userId, $d['price'], $useWalletCredit, 'کسر موجودی کیف پول برای پرداخت ارز دیجیتال');
        $payableCryptoToman = (int)$wp['payable'];
        if ($payableCryptoToman <= 0) { throw new RuntimeException('مبلغ باقی‌مانده برای درگاه صفر است؛ لطفاً پرداخت از کیف پول را انتخاب کنید.'); }
        $d['price'] = $payableCryptoToman;
        $meta = json_encode(['source'=>'mini_app_plisio','asset'=>$asset,'original_price'=>$d['originalPrice'],'discount_code'=>$discountCode,'discount_amount'=>(int)($d['discount']['discount_amount'] ?? 0),'wallet_credit_used'=>(int)$wp['wallet_applied'],'final_price'=>$d['price']], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        $orderId = crypto_insert_order($d, $userId, $planId, 'CRYPTO_PLISIO', $meta, null, 'WAITING_PAYMENT');
        $cpStmt = $pdo->prepare("INSERT INTO crypto_payments(order_id,user_id,amount,currency,provider,payment_type,status,raw_request) VALUES(?,?,?,?,?,?,?,?)");
        $cpStmt->execute([$orderId,$userId,$d['price'],'IRT','Plisio','order','PENDING',$meta]);
        $cryptoId=(int)$pdo->lastInsertId();
        $pdo->prepare("UPDATE orders SET crypto_payment_id=? WHERE id=?")->execute([$cryptoId,$orderId]);
        $invoice = plisio_create_invoice('ORD-'.$orderId, 'GEM ACC order #'.$orderId, $d['price'], 'order', $asset);
        $pdo->prepare("UPDATE crypto_payments SET provider_invoice_id=?, provider_order_id=?, payment_url=?, crypto_currency=?, raw_response=? WHERE id=?")->execute([$invoice['txn_id'],$invoice['txn_id'],$invoice['invoice_url'],$invoice['currency'],json_encode($invoice['raw'], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES),$cryptoId]);
        $pdo->commit();
        crypto_send_user_gateway_link($userId, $orderId, $invoice['invoice_url'], $d['price']);
        crypto_json(['ok'=>true,'provider'=>'Plisio','message'=>'فاکتور پرداخت Plisio ساخته شد. لینک در چت ربات هم ارسال شد.','payment_url'=>$invoice['invoice_url'],'asset'=>$asset,'order_id'=>$orderId,'crypto_payment_id'=>$cryptoId,'amount'=>$d['price'],'wallet_credit_used'=>(int)$wp['wallet_applied'],'selected_quote'=>manual_crypto_selected_quote($d['price'],$asset),'quote'=>manual_crypto_quote($d['price']),'invoice_crypto_amount'=>$invoice['crypto_amount'] ?? null,'invoice_currency'=>$invoice['currency'] ?? null]);
    }

    if ($action !== 'manual_submit') throw new RuntimeException('دستور پرداخت ارز نامعتبر است.');
    $cfg = manual_crypto_require_enabled();
    if ($asset === '') throw new RuntimeException('لطفاً ارز پرداخت را انتخاب کنید.');
    $w = crypto_asset_wallet_payload($cfg, $asset);
    $receiptText = trim((string)($input['receipt_text'] ?? ''));
    $receiptFile = manual_crypto_upload_receipt($userId, 'crypto_order');
    if ($receiptText === '' && !$receiptFile) crypto_json(['ok'=>false,'error'=>'عکس رسید یا هش/TxID تراکنش الزامی است']);

    $pdo->beginTransaction();
    $wp = crypto_wallet_deduct_locked($pdo, $userId, $d['price'], $useWalletCredit, 'کسر موجودی کیف پول برای پرداخت دستی ارز دیجیتال');
    $payableCryptoToman = (int)$wp['payable'];
    if ($payableCryptoToman <= 0) { throw new RuntimeException('مبلغ باقی‌مانده برای پرداخت دستی صفر است؛ لطفاً پرداخت از کیف پول را انتخاب کنید.'); }
    $d['price'] = $payableCryptoToman;
    $meta = json_encode(['source'=>'mini_app_crypto_manual','asset'=>$w['asset'],'wallet'=>['address'=>$w['address'],'network'=>$w['network']], 'selected_quote'=>manual_crypto_selected_quote($d['price'],$w['asset']), 'quote'=>manual_crypto_quote($d['price']), 'original_price'=>$d['originalPrice'],'discount_code'=>$discountCode,'discount_amount'=>(int)($d['discount']['discount_amount'] ?? 0),'wallet_credit_used'=>(int)$wp['wallet_applied'],'final_price'=>$d['price'],'receipt_text'=>$receiptText], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    $orderId = crypto_insert_order($d, $userId, $planId, 'CRYPTO', $meta, $receiptFile);
    $cryptoStmt = $pdo->prepare("INSERT INTO crypto_payments(order_id,user_id,amount,currency,crypto_currency,network,wallet_address,provider,payment_type,status,receipt_file_id,receipt_text,raw_request) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)");
    $cryptoStmt->execute([$orderId,$userId,$d['price'],'IRT',$w['asset'],$w['network'],$w['address'],'ManualCrypto','order','PENDING',$receiptFile,$receiptText,$meta]);
    $cryptoId=(int)$pdo->lastInsertId();
    $pdo->prepare("UPDATE orders SET crypto_payment_id=? WHERE id=?")->execute([$cryptoId,$orderId]);
    $pdo->commit();

    $adminMsg = "🪙 رسید پرداخت ارز دیجیتال جدید\n\n👤 کاربر: {$userId}\n📦 سفارش: #{$orderId}\n💰 مبلغ: " . money($d['price']) . "\n";
    if ($receiptText !== '') $adminMsg .= "\n📝 رسید/TxID:\n{$receiptText}\n";
    $buttons = ['inline_keyboard'=>[
        [['text'=>'✅ تأیید سفارش','callback_data'=>"ADMIN_APPROVE_ORDER__{$orderId}"], ['text'=>'❌ رد سفارش','callback_data'=>"ADMIN_REJECT_ORDER__{$orderId}"]],
        [['text'=>'⚠️ اخطار فیش فیک','callback_data'=>"ADMIN_FAKE_RECEIPT_ORDER__{$orderId}"]],
    ]];
    manual_crypto_notify_admins($adminMsg, $buttons, $receiptFile);
    tg('sendMessage',['chat_id'=>$userId,'text'=>"✅ رسید ارز دیجیتال سفارش #{$orderId} ثبت شد. پس از بررسی ادمین، سرویس برای شما ارسال می‌شود."]);
    crypto_json(['ok'=>true,'message'=>'رسید ارز دیجیتال ثبت شد و منتظر تأیید ادمین است.','order_id'=>$orderId,'crypto_payment_id'=>$cryptoId]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    error_log('[buy_with_crypto] '.$e->getMessage());
    crypto_json(['ok'=>false,'error'=>$e->getMessage()]);
}
