<?php
/**
 * UPI Pool Manager
 * Handles UPI rotation and selection logic
 */

class UpiPoolManager {
    private $conn;
    
    public function __construct($pdo_connection) {
        $this->conn = $pdo_connection;
    }
    
    /**
     * Get next available UPI ID based on rotation logic
     * @return array|false UPI details or false if none available
     */
    public function getNextUPI() {
        try {
            // Get rotation settings
            $settings = $this->getSettings();
            
            if (!$settings['upi_rotation_enabled']) {
                // If rotation disabled, get first active UPI
                return $this->getFirstActiveUPI();
            }
            
            $interval = $settings['upi_rotation_interval']; // in seconds
            
            // Get UPI that hasn't been used recently or has least usage
            $query = "
                SELECT * FROM upi_pool 
                WHERE status = 'active' 
                AND current_usage < daily_limit
                ORDER BY 
                    CASE 
                        WHEN last_used IS NULL THEN 0
                        WHEN TIMESTAMPDIFF(SECOND, last_used, NOW()) >= ? THEN 1
                        ELSE 2
                    END,
                    last_used ASC,
                    current_usage ASC
                LIMIT 1
            ";
            
            $stmt = $this->conn->prepare($query);
            $stmt->execute([$interval]);
            $upi = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($upi) {
                // Update last_used timestamp
                $this->updateUPIUsage($upi['id']);
                return $upi;
            }
            
            return false;
            
        } catch (Exception $e) {
            error_log("UPI Pool Error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get first active UPI (when rotation is disabled)
     */
    private function getFirstActiveUPI() {
        $stmt = $this->conn->prepare("
            SELECT * FROM upi_pool 
            WHERE status = 'active' 
            AND current_usage < daily_limit
            ORDER BY id ASC 
            LIMIT 1
        ");
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    /**
     * Update UPI usage timestamp
     */
    private function updateUPIUsage($upi_id) {
        $stmt = $this->conn->prepare("
            UPDATE upi_pool 
            SET last_used = NOW(), 
                total_transactions = total_transactions + 1 
            WHERE id = ?
        ");
        $stmt->execute([$upi_id]);
    }
    
    /**
     * Log UPI assignment to order
     */
    public function logUPIAssignment($upi_id, $order_id, $amount) {
        try {
            $stmt = $this->conn->prepare("
                INSERT INTO upi_rotation_log 
                (upi_id, order_id, amount, assigned_at, status) 
                VALUES (?, ?, ?, NOW(), 'assigned')
            ");
            $stmt->execute([$upi_id, $order_id, $amount]);
            
            // Update usage removed from here. Now handled in updateTransactionStatus on SUCCESS only.
            
        } catch (Exception $e) {
            error_log("UPI Log Error: " . $e->getMessage());
        }
    }
    
    /**
     * Update UPI transaction status
     */
    public function updateTransactionStatus($order_id, $status) {
        try {
            // Check current status to prevent double counting
            $check = $this->conn->prepare("SELECT status, upi_id, amount FROM upi_rotation_log WHERE order_id = ?");
            $check->execute([$order_id]);
            $current = $check->fetch(PDO::FETCH_ASSOC);

            $stmt = $this->conn->prepare("
                UPDATE upi_rotation_log 
                SET status = ? 
                WHERE order_id = ?
            ");
            $stmt->execute([$status, $order_id]);
            
            // If transitioning to success, update pool usage
            if ($current && $current['status'] != 'success' && $status == 'success') {
                 $upd = $this->conn->prepare("UPDATE upi_pool SET current_usage = current_usage + ? WHERE upi_id = ?");
                 $upd->execute([$current['amount'], $current['upi_id']]);
            }
            
            // Update success rate
            if ($status == 'success' || $status == 'failed') {
                $this->updateSuccessRate($order_id);
            }
            
        } catch (Exception $e) {
            error_log("UPI Status Update Error: " . $e->getMessage());
        }
    }
    
    /**
     * Update UPI success rate
     */
    private function updateSuccessRate($order_id) {
        try {
            // Get UPI ID from log
            $stmt = $this->conn->prepare("SELECT upi_id FROM upi_rotation_log WHERE order_id = ?");
            $stmt->execute([$order_id]);
            $log = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($log) {
                // Calculate success rate
                $stmt = $this->conn->prepare("
                    SELECT 
                        COUNT(*) as total,
                        SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as successful
                    FROM upi_rotation_log 
                    WHERE upi_id = ?
                ");
                $stmt->execute([$log['upi_id']]);
                $stats = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if ($stats['total'] > 0) {
                    $success_rate = ($stats['successful'] / $stats['total']) * 100;
                    
                    $stmt = $this->conn->prepare("
                        UPDATE upi_pool 
                        SET success_rate = ? 
                        WHERE upi_id = ?
                    ");
                    $stmt->execute([$success_rate, $log['upi_id']]);
                }
            }
        } catch (Exception $e) {
            error_log("Success Rate Update Error: " . $e->getMessage());
        }
    }
    
    /**
     * Get settings
     */
    private function getSettings() {
        $stmt = $this->conn->prepare("SELECT * FROM settings LIMIT 1");
        $stmt->execute();
        $settings = $stmt->fetch(PDO::FETCH_ASSOC);
        
        // If no settings found, use empty array to trigger defaults
        if (!$settings) {
            $settings = [];
        }
        
        return [
            'upi_rotation_enabled' => $settings['upi_rotation_enabled'] ?? 1,
            'upi_rotation_interval' => $settings['upi_rotation_interval'] ?? 60,
            'bank_upi_commission' => $settings['bank_upi_commission'] ?? 2.00,
            'bank_upi_fixed' => $settings['bank_upi_fixed'] ?? 0.00,
            'bank_upi_payout_commission' => $settings['bank_upi_payout_commission'] ?? 0.00,
            'bank_upi_payout_fixed' => $settings['bank_upi_payout_fixed'] ?? 0.00,
            'default_gateway' => $settings['default_gateway'] ?? 'rspay'
        ];
    }
    
    /**
     * Get gateway settings
     */
    public function getGatewaySettings() {
        return $this->getSettings();
    }
    
    /**
     * Reset daily usage (call this via cron at midnight)
     */
    public function resetDailyUsage() {
        try {
            $stmt = $this->conn->prepare("UPDATE upi_pool SET current_usage = 0.00");
            $stmt->execute();
            return true;
        } catch (Exception $e) {
            error_log("Reset Daily Usage Error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get all active UPIs
     */
    public function getAllActiveUPIs() {
        $stmt = $this->conn->prepare("
            SELECT * FROM upi_pool 
            WHERE status = 'active' 
            ORDER BY last_used ASC
        ");
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Get UPI statistics
     */
    public function getUPIStats($upi_id) {
        $stmt = $this->conn->prepare("
            SELECT 
                COUNT(*) as total_orders,
                SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as successful_orders,
                SUM(CASE WHEN status = 'success' THEN amount ELSE 0 END) as total_amount,
                AVG(CASE WHEN status = 'success' THEN amount ELSE NULL END) as avg_amount
            FROM upi_rotation_log 
            WHERE upi_id = ?
        ");
        $stmt->execute([$upi_id]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
}

