<?php
/**
 * WithdrawalService - Manages withdrawal requests
 * Location: app/Services/WithdrawalService.php
 */
class WithdrawalService {
    private $db;
    
    public function __construct() {
        $this->db = Database::getInstance()->getConnection();
    }
    
    /**
     * Create withdrawal request - DEDUCT IMMEDIATELY
     */
    public function createRequest($user_id, $wallet_type, $amount, $bank_details) {
        $this->db->begin_transaction();
        
        try {
            // Get wallet
            $walletService = new WalletService();
            $wallet = $walletService->getWallet($user_id, $wallet_type);
            
            if (!$wallet) {
                throw new Exception("Wallet not found");
            }
            
            // Validate withdrawable wallet types
            $allowed_wallets = ['main_balance', 'security_refundable'];
            if (!in_array($wallet_type, $allowed_wallets)) {
                throw new Exception("Cannot withdraw from this wallet type");
            }
            
            if ($wallet['balance'] < $amount) {
                throw new Exception("Insufficient balance. Available: ₦" . number_format($wallet['balance'], 2));
            }
            
            // DEDUCT FROM WALLET IMMEDIATELY
            $stmt = $this->db->prepare("
                UPDATE user_wallets 
                SET balance = balance - ? 
                WHERE id = ? AND balance >= ?
            ");
            $stmt->bind_param("did", $amount, $wallet['id'], $amount);
            $stmt->execute();
            
            if ($stmt->affected_rows === 0) {
                throw new Exception("Failed to deduct amount from wallet");
            }
            
            // Create withdrawal request
            $reference = 'WD_' . strtoupper(uniqid());
            $stmt = $this->db->prepare("
                INSERT INTO withdrawal_requests 
                (user_id, wallet_id, wallet_type, amount, bank_name, account_number, account_name, reference, status, created_at) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', NOW())
            ");
            $stmt->bind_param(
                "iisdssss",
                $user_id,
                $wallet['id'],
                $wallet_type,
                $amount,
                $bank_details['bank_name'],
                $bank_details['account_number'],
                $bank_details['account_name'],
                $reference
            );
            $stmt->execute();
            
            $this->db->commit();
            return ['success' => true, 'reference' => $reference];
            
        } catch (Exception $e) {
            $this->db->rollback();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * Approve withdrawal request - MONEY ALREADY DEDUCTED
     */
    public function approveRequest($request_id, $admin_id) {
        $this->db->begin_transaction();
        
        try {
            // Get request details
            $request = $this->getRequestById($request_id);
            
            if (!$request || $request['status'] !== 'pending') {
                throw new Exception("Invalid or already processed request");
            }
            
            // Record transaction
            $walletService = new WalletService();
            $walletService->recordTransaction([
                'user_id' => $request['user_id'],
                'from_wallet_id' => $request['wallet_id'],
                'transaction_type' => 'withdrawal',
                'amount' => $request['amount'],
                'balance_before' => 0,
                'balance_after' => 0,
                'description' => "Withdrawal approved - {$request['bank_name']} ({$request['account_number']})",
                'reference' => $request['reference'],
                'status' => 'completed'
            ]);
            
            // Update request status to approved
            $stmt = $this->db->prepare("
                UPDATE withdrawal_requests 
                SET status = 'approved', 
                    processed_by = ?, 
                    processed_at = NOW() 
                WHERE id = ?
            ");
            $stmt->bind_param("ii", $admin_id, $request_id);
            $stmt->execute();
            
            $this->db->commit();
            return ['success' => true];
            
        } catch (Exception $e) {
            $this->db->rollback();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * Reject withdrawal request - REFUND TO WALLET
     */
    public function rejectRequest($request_id, $admin_id, $reason) {
        $this->db->begin_transaction();
        
        try {
            // Get request details
            $request = $this->getRequestById($request_id);
            
            if (!$request || $request['status'] !== 'pending') {
                throw new Exception("Invalid or already processed request");
            }
            
            // REFUND BACK TO WALLET
            $stmt = $this->db->prepare("
                UPDATE user_wallets 
                SET balance = balance + ? 
                WHERE id = ?
            ");
            $stmt->bind_param("di", $request['amount'], $request['wallet_id']);
            $stmt->execute();
            
            // Update request status
            $stmt = $this->db->prepare("
                UPDATE withdrawal_requests 
                SET status = 'rejected', 
                    processed_by = ?, 
                    processed_at = NOW(), 
                    reject_reason = ? 
                WHERE id = ?
            ");
            $stmt->bind_param("isi", $admin_id, $reason, $request_id);
            $stmt->execute();
            
            $this->db->commit();
            return ['success' => true];
            
        } catch (Exception $e) {
            $this->db->rollback();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * Cancel withdrawal request (by user)
     */
    public function cancelRequest($request_id, $user_id) {
        $stmt = $this->db->prepare("
            UPDATE withdrawal_requests 
            SET status = 'cancelled' 
            WHERE id = ? AND user_id = ? AND status = 'pending'
        ");
        $stmt->bind_param("ii", $request_id, $user_id);
        
        if ($stmt->execute() && $stmt->affected_rows > 0) {
            return ['success' => true];
        }
        
        return ['success' => false, 'error' => 'Request not found or cannot be cancelled'];
    }
    
    /**
     * Get withdrawal request by ID
     */
    public function getRequestById($request_id) {
        $stmt = $this->db->prepare("
            SELECT wr.*, u.email, uw.wallet_type 
            FROM withdrawal_requests wr
            JOIN users u ON wr.user_id = u.id
            JOIN user_wallets uw ON wr.wallet_id = uw.id
            WHERE wr.id = ?
        ");
        $stmt->bind_param("i", $request_id);
        $stmt->execute();
        return $stmt->get_result()->fetch_assoc();
    }
    
    /**
     * Get user withdrawal requests
     */
    public function getUserRequests($user_id, $limit = 20) {
        $stmt = $this->db->prepare("
            SELECT wr.*, uw.wallet_type 
            FROM withdrawal_requests wr
            JOIN user_wallets uw ON wr.wallet_id = uw.id
            WHERE wr.user_id = ?
            ORDER BY wr.created_at DESC
            LIMIT ?
        ");
        $stmt->bind_param("ii", $user_id, $limit);
        $stmt->execute();
        return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    }
    
    /**
     * Get pending withdrawal requests (for admin)
     */
    public function getPendingRequests($limit = 50) {
        $stmt = $this->db->prepare("
            SELECT wr.*, u.email, u.user_type, uw.wallet_type 
            FROM withdrawal_requests wr
            JOIN users u ON wr.user_id = u.id
            JOIN user_wallets uw ON wr.wallet_id = uw.id
            WHERE wr.status = 'pending'
            ORDER BY wr.created_at ASC
            LIMIT ?
        ");
        $stmt->bind_param("i", $limit);
        $stmt->execute();
        return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    }
}