<?php
/**
 * UPI Auto-Verification Engine
 * Validates UTR, checks duplicates, verifies amounts, auto-approves deposits
 */

class UpiVerifier {
    
    // UTR validation: 12-digit numeric (standard UPI) or 6-30 alphanumeric
    public static function validateUtrFormat($utr) {
        $utr = trim($utr);
        if (empty($utr)) {
            return ['valid' => false, 'error' => 'UTR number is required'];
        }
        if (strlen($utr) < 6 || strlen($utr) > 30) {
            return ['valid' => false, 'error' => 'UTR must be 6-30 characters'];
        }
        if (!preg_match('/^[0-9A-Za-z]+$/', $utr)) {
            return ['valid' => false, 'error' => 'UTR must contain only alphanumeric characters'];
        }
        return ['valid' => true, 'utr' => $utr];
    }
    
    // Check if UTR has been used before (across both tables)
    public static function checkDuplicateUtr($utr, $excludePaymentId = null) {
        // Check in upi_payments (completed/pending)
        $sql = "SELECT id, user_id, amount, status FROM upi_payments WHERE utr_number = :utr AND utr_number != '' AND utr_number IS NOT NULL";
        $params = ['utr' => $utr];
        
        if ($excludePaymentId) {
            $sql .= " AND id != :exclude_id";
            $params['exclude_id'] = $excludePaymentId;
        }
        
        $existing = dbFetch($sql, $params);
        if ($existing) {
            return [
                'duplicate' => true,
                'error' => 'This UTR number has already been used for another transaction',
                'existing_id' => $existing['id'],
                'existing_status' => $existing['status']
            ];
        }
        
        // Check in deposits table too
        $sql2 = "SELECT id, user_id, amount, status FROM deposits WHERE utr_number = :utr AND utr_number != '' AND utr_number IS NOT NULL";
        $existing2 = dbFetch($sql2, ['utr' => $utr]);
        if ($existing2) {
            return [
                'duplicate' => true,
                'error' => 'This UTR number has already been used for a deposit',
                'existing_id' => $existing2['id'],
                'existing_status' => $existing2['status']
            ];
        }
        
        return ['duplicate' => false];
    }
    
    // Validate that amounts match (within tolerance)
    public static function validateAmount($submittedAmount, $expectedAmount, $tolerance = 0.01) {
        $submittedAmount = (float)$submittedAmount;
        $expectedAmount = (float)$expectedAmount;
        
        if ($submittedAmount <= 0) {
            return ['valid' => false, 'error' => 'Invalid amount'];
        }
        
        $diff = abs($submittedAmount - $expectedAmount);
        if ($diff > $tolerance) {
            return [
                'valid' => false, 
                'error' => 'Amount mismatch. Expected ₹' . number_format($expectedAmount, 2) . ' but got ₹' . number_format($submittedAmount, 2)
            ];
        }
        
        return ['valid' => true];
    }
    
    /**
     * Auto-verify a UPI payment
     * Runs all checks and auto-approves if valid
     * 
     * @param int $paymentId - upi_payments.id
     * @param string $utr - UTR number submitted by user
     * @param string|null $ipAddress
     * @param string|null $deviceInfo
     * @return array - Result with success/error
     */
    public static function autoVerifyDeposit($paymentId, $utr, $ipAddress = null, $deviceInfo = null) {
        // 1. Get payment record
        $payment = dbFetch(
            "SELECT * FROM upi_payments WHERE id = :id AND status = 'pending'",
            ['id' => $paymentId]
        );
        
        if (!$payment) {
            return ['success' => false, 'error' => 'Payment not found or already processed'];
        }
        
        // 2. Validate UTR format
        $utrCheck = self::validateUtrFormat($utr);
        if (!$utrCheck['valid']) {
            self::logVerification($paymentId, 'failed', 'UTR format invalid: ' . $utrCheck['error']);
            return ['success' => false, 'error' => $utrCheck['error']];
        }
        
        // 3. Check for duplicate UTR
        $dupCheck = self::checkDuplicateUtr($utr, $paymentId);
        if ($dupCheck['duplicate']) {
            self::logVerification($paymentId, 'failed', 'Duplicate UTR: ' . $utr);
            // Mark payment as failed
            dbUpdate('upi_payments', [
                'utr_number' => $utr,
                'status' => 'failed',
                'rejection_reason' => 'Duplicate UTR number detected',
                'verification_notes' => 'Auto-rejected: UTR already used in payment #' . ($dupCheck['existing_id'] ?? 'unknown'),
                'ip_address' => $ipAddress,
                'device_info' => $deviceInfo
            ], 'id = :id', ['id' => $paymentId]);
            
            return ['success' => false, 'error' => $dupCheck['error']];
        }
        
        // 4. All checks passed — auto-approve
        try {
            dbBeginTransaction();
            
            $userId = $payment['user_id'];
            $amount = (float)$payment['amount'];
            
            // Update payment status
            dbUpdate('upi_payments', [
                'utr_number' => $utr,
                'status' => 'completed',
                'auto_verified' => 1,
                'verification_notes' => 'Auto-verified: UTR valid, no duplicates',
                'completed_at' => date('Y-m-d H:i:s'),
                'ip_address' => $ipAddress,
                'device_info' => $deviceInfo
            ], 'id = :id', ['id' => $paymentId]);
            
            // Update user wallet
            $wallet = dbFetch("SELECT * FROM user_wallets WHERE user_id = :uid", ['uid' => $userId]);
            if ($wallet) {
                dbQuery(
                    "UPDATE user_wallets SET balance = balance + :amt1, total_deposit = COALESCE(total_deposit, 0) + :amt2 WHERE user_id = :uid",
                    ['amt1' => $amount, 'amt2' => $amount, 'uid' => $userId]
                );
            } else {
                dbInsert('user_wallets', [
                    'user_id' => $userId,
                    'balance' => $amount,
                    'total_deposit' => $amount
                ]);
            }
            
            // Apply bonus if enabled
            $bonusAmount = 0;
            $bonusEnabled = getSetting('deposit_bonus_enabled', '0') === '1';
            $bonusMinAmount = (float)getSetting('deposit_bonus_min_amount', 0);
            
            if ($bonusEnabled && $amount >= $bonusMinAmount) {
                $bonusTier = dbFetch(
                    "SELECT * FROM deposit_bonus_tiers WHERE min_amount <= :amt AND status = 'active' ORDER BY min_amount DESC LIMIT 1",
                    ['amt' => $amount]
                );
                
                if ($bonusTier && $bonusTier['bonus_percent'] > 0) {
                    $bonusPercent = (float)$bonusTier['bonus_percent'];
                    $bonusMaxBonus = (float)getSetting('deposit_bonus_max_bonus', 0);
                    $bonusAmount = $amount * ($bonusPercent / 100);
                    
                    if ($bonusMaxBonus > 0 && $bonusAmount > $bonusMaxBonus) {
                        $bonusAmount = $bonusMaxBonus;
                    }
                    
                    // Add bonus to wallet
                    dbQuery(
                        "UPDATE user_wallets SET bonus_balance = COALESCE(bonus_balance, 0) + :bonus WHERE user_id = :uid",
                        ['bonus' => $bonusAmount, 'uid' => $userId]
                    );
                    
                    // Set turnover requirement
                    $turnoverMultiplier = (float)getSetting('bonus_turnover_multiplier', 30);
                    $turnoverRequired = $bonusAmount * $turnoverMultiplier;
                    dbQuery(
                        "UPDATE user_wallets SET turnover_required = COALESCE(turnover_required, 0) + :tr WHERE user_id = :uid",
                        ['tr' => $turnoverRequired, 'uid' => $userId]
                    );
                    
                    // Create bonus transaction
                    dbInsert('transactions', [
                        'transaction_id' => generateTransactionId('BON'),
                        'user_id' => $userId,
                        'type' => 'bonus',
                        'amount' => $bonusAmount,
                        'balance_after' => ($wallet['balance'] ?? 0) + $amount + $bonusAmount,
                        'description' => 'Deposit Bonus ' . $bonusPercent . '% (Auto-verified)',
                        'status' => 'completed'
                    ]);
                }
            }
            
            // Create deposit record
            $depositId = dbInsert('deposits', [
                'deposit_id' => 'DEP' . strtoupper(substr(md5(uniqid()), 0, 10)),
                'user_id' => $userId,
                'amount' => $amount,
                'payment_method' => 'upi',
                'transaction_id' => $utr,
                'utr_number' => $utr,
                'bonus_applied' => $bonusAmount,
                'status' => 'approved',
                'auto_verified' => 1,
                'processed_at' => date('Y-m-d H:i:s'),
                'ip_address' => $ipAddress,
                'device_info' => $deviceInfo
            ]);
            
            // Create deposit transaction
            $newBalance = ($wallet['balance'] ?? 0) + $amount + $bonusAmount;
            dbInsert('transactions', [
                'transaction_id' => generateTransactionId('DEP'),
                'user_id' => $userId,
                'type' => 'deposit',
                'amount' => $amount,
                'balance_after' => $newBalance,
                'reference_id' => $depositId,
                'description' => "UPI Deposit (Auto-verified) UTR: {$utr}",
                'status' => 'completed'
            ]);
            
            // Send notification
            dbInsert('notifications', [
                'user_id' => $userId,
                'type' => 'deposit',
                'title' => 'Deposit Approved',
                'message' => 'Your deposit of ₹' . number_format($amount, 2) . ' has been auto-verified and credited.' . 
                    ($bonusAmount > 0 ? ' Bonus: ₹' . number_format($bonusAmount, 2) : '')
            ]);
            
            dbCommit();
            
            self::logVerification($paymentId, 'success', "Auto-approved: ₹{$amount}, UTR: {$utr}, Bonus: ₹{$bonusAmount}");
            
            return [
                'success' => true,
                'message' => 'Deposit verified and credited successfully!',
                'amount' => $amount,
                'bonus' => $bonusAmount,
                'new_balance' => $newBalance,
                'deposit_id' => $depositId
            ];
            
        } catch (Exception $e) {
            dbRollback();
            error_log("Auto-verify error: " . $e->getMessage());
            self::logVerification($paymentId, 'error', 'Exception: ' . $e->getMessage());
            return ['success' => false, 'error' => 'Verification failed. Please contact support.'];
        }
    }
    
    // Log verification attempt
    public static function logVerification($paymentId, $status, $notes) {
        try {
            logActivity('system', 0, 'upi_verify_' . $status, "Payment #{$paymentId}: {$notes}");
        } catch (Exception $e) {
            error_log("Verification log error: " . $e->getMessage());
        }
    }
    
    /**
     * Generate UPI payment link
     */
    public static function generateUpiLink($upiId, $merchantName, $amount, $txnRef) {
        $params = [
            'pa' => $upiId,
            'pn' => $merchantName,
            'am' => number_format($amount, 2, '.', ''),
            'cu' => 'INR',
            'tn' => 'Deposit ' . $txnRef
        ];
        return 'upi://pay?' . http_build_query($params);
    }
    
    /**
     * Generate QR code SVG for UPI payment
     * Pure PHP implementation - no external libraries needed
     */
    public static function generateQrCodeDataUrl($data) {
        // Use Google Charts API for QR (lightweight, no library needed)
        $qrUrl = 'https://chart.googleapis.com/chart?cht=qr&chs=300x300&chl=' . urlencode($data) . '&choe=UTF-8';
        return $qrUrl;
    }
    
    /**
     * Generate deep links for popular UPI apps
     */
    public static function getAppDeepLinks($upiLink) {
        return [
            'gpay' => str_replace('upi://', 'tez://upi/', $upiLink),
            'phonepe' => str_replace('upi://', 'phonepe://', $upiLink),
            'paytm' => str_replace('upi://', 'paytmmp://', $upiLink),
            'generic' => $upiLink
        ];
    }
}
