<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

require APPPATH . '/libraries/BaseController.php';

class Transaction extends BaseController
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('common');
        $this->load->model('customer_model');
        $this->isLoggedIn();
    }

    /**
     * Display transactions listing page
     */
    public function index()
    {
        $this->global['pageTitle'] = 'StreamAdmin : Withdrawal Transactions';

        // Fetch all withdrawals from Firebase
        $withdrawals = $this->common->readdatafromcollectionwhereclause('Withdraws');
        $withdrawals = is_array($withdrawals) ? $withdrawals : [];

        // Sort by createdAtMs (newest first)
        if (!empty($withdrawals)) {
            uasort($withdrawals, function ($a, $b) {
                $aTime = isset($a['createdAtMs']) ? (int)$a['createdAtMs'] : 0;
                $bTime = isset($b['createdAtMs']) ? (int)$b['createdAtMs'] : 0;
                return $bTime <=> $aTime;
            });
        }

        // Prepare containers
        $enrichedWithdrawals = [];
        $totals = [
            'total'         => 0,
            'pending'       => 0,
            'approved'      => 0,
            'rejected'      => 0,
            'totalAmount'   => 0.0,
            'latestRequest' => null,
        ];

        // Fetch user details for each withdrawal
        foreach ($withdrawals as $id => $withdrawal) {
            if (!is_array($withdrawal)) {
                continue;
            }

            $withdrawal['id'] = $id;

            // Get user details
            if (!empty($withdrawal['userId'])) {
                try {
                    $userData = $this->customer_model->get_customerdetails($withdrawal['userId']);
                    if (!empty($userData)) {
                        $withdrawal['userName'] = isset($userData['fullName']) ? $userData['fullName'] : 'N/A';
                        $withdrawal['userEmail'] = isset($userData['email']) ? $userData['email'] : (!empty($withdrawal['email']) ? $withdrawal['email'] : 'N/A');
                        $withdrawal['currentEarning'] = isset($userData['Earning']) ? $userData['Earning'] : (!empty($withdrawal['Earning']) ? $withdrawal['Earning'] : 'N/A');
                    } else {
                        $withdrawal['userName'] = 'N/A';
                        $withdrawal['userEmail'] = !empty($withdrawal['email']) ? $withdrawal['email'] : 'N/A';
                        $withdrawal['currentEarning'] = !empty($withdrawal['Earning']) ? $withdrawal['Earning'] : 'N/A';
                    }
                } catch (Exception $e) {
                    $withdrawal['userName'] = 'N/A';
                    $withdrawal['userEmail'] = !empty($withdrawal['email']) ? $withdrawal['email'] : 'N/A';
                    $withdrawal['currentEarning'] = !empty($withdrawal['Earning']) ? $withdrawal['Earning'] : 'N/A';
                }
            } else {
                $withdrawal['userName'] = 'N/A';
                $withdrawal['userEmail'] = !empty($withdrawal['email']) ? $withdrawal['email'] : 'N/A';
                $withdrawal['currentEarning'] = !empty($withdrawal['Earning']) ? $withdrawal['Earning'] : 'N/A';
            }

            $status = isset($withdrawal['status']) ? strtolower((string)$withdrawal['status']) : 'pending';
            $amount = isset($withdrawal['amount']) ? (float)$withdrawal['amount'] : 0.0;
            $createdAtMs = isset($withdrawal['createdAtMs']) ? (int)$withdrawal['createdAtMs'] : null;

            // Update totals
            $totals['total']++;
            $totals['totalAmount'] += $amount;
            if (isset($totals[$status])) {
                $totals[$status]++;
            }
            if ($createdAtMs) {
                if ($totals['latestRequest'] === null || $createdAtMs > $totals['latestRequest']) {
                    $totals['latestRequest'] = $createdAtMs;
                }
            }

            $enrichedWithdrawals[$id] = $withdrawal;
        }

        $averageAmount = $totals['total'] > 0 ? $totals['totalAmount'] / $totals['total'] : 0.0;
        $totals['averageAmount'] = $averageAmount;

        $data = [
            'withdrawals'      => $enrichedWithdrawals,
            'withdrawalStats'  => [
                'total'         => $totals['total'],
                'pending'       => $totals['pending'],
                'approved'      => $totals['approved'],
                'rejected'      => $totals['rejected'],
                'totalAmount'   => $totals['totalAmount'],
                'averageAmount' => $averageAmount,
                'latestRequest' => $totals['latestRequest'],
            ],
        ];

        $this->loadViews("transactions", $this->global, $data, NULL);
    }

    /**
     * Get withdrawals by status (AJAX)
     */
    public function getWithdrawalsByStatus()
    {
        $status = $this->input->post('status');
        $date = $this->input->post('date');
        
        if ($status === 'All' || empty($status)) {
            $withdrawals = $this->common->readdatafromcollectionwhereclause('Withdraws');
        } else {
            $withdrawals = $this->common->readdatafromcollectionwhereclause('Withdraws', 'status', '==', strtolower($status));
        }
        
        // Filter by date if provided
        if (!empty($date)) {
            $dateTimestamp = strtotime($date) * 1000;
            $endTimestamp = $dateTimestamp + (24 * 60 * 60 * 1000); // Add 24 hours
            
            $withdrawals = array_filter($withdrawals, function($withdrawal) use ($dateTimestamp, $endTimestamp) {
                $createdAt = isset($withdrawal['createdAtMs']) ? $withdrawal['createdAtMs'] : 0;
                return $createdAt >= $dateTimestamp && $createdAt < $endTimestamp;
            });
        }
        
        // Sort by createdAtMs (newest first)
        if (!empty($withdrawals)) {
            uasort($withdrawals, function($a, $b) {
                $aTime = isset($a['createdAtMs']) ? $a['createdAtMs'] : 0;
                $bTime = isset($b['createdAtMs']) ? $b['createdAtMs'] : 0;
                return $bTime - $aTime;
            });
        }
        
        // Fetch user details for each withdrawal
        $result = array();
        foreach ($withdrawals as $id => $withdrawal) {
            $withdrawal['id'] = $id;
            
            // Get user details
            if (isset($withdrawal['userId'])) {
                try {
                    $userData = $this->customer_model->get_customerdetails($withdrawal['userId']);
                    if (!empty($userData)) {
                        $withdrawal['userName'] = isset($userData['name']) ? $userData['name'] : 'N/A';
                        $withdrawal['currentEarning'] = isset($userData['Earning']) ? $userData['Earning'] : 0;
                    } else {
                        $withdrawal['userName'] = 'N/A';
                        $withdrawal['currentEarning'] = 0;
                    }
                } catch (Exception $e) {
                    $withdrawal['userName'] = 'N/A';
                    $withdrawal['currentEarning'] = 0;
                }
            } else {
                $withdrawal['userName'] = 'N/A';
                $withdrawal['currentEarning'] = 0;
            }
            
            $result[] = $withdrawal;
        }
        
        echo json_encode(array('status' => true, 'data' => $result));
    }

    /**
     * Approve withdrawal request
     */
    public function approveWithdrawal()
    {
        $withdrawalId = $this->input->post('withdrawalId');
        
        if (empty($withdrawalId)) {
            echo json_encode(array('status' => false, 'message' => 'Withdrawal ID is required'));
            return;
        }
        
        try {
            // Get withdrawal details
            $withdrawals = $this->common->readdatafromcollectionwhereclause('Withdraws');
            
            if (!isset($withdrawals[$withdrawalId])) {
                echo json_encode(array('status' => false, 'message' => 'Withdrawal not found'));
                return;
            }
            
            $withdrawal = $withdrawals[$withdrawalId];
            
            // Check if already processed
            if (isset($withdrawal['status']) && $withdrawal['status'] !== 'pending') {
                echo json_encode(array('status' => false, 'message' => 'Withdrawal already processed'));
                return;
            }
            
            // Get user current balance
            $userDoc = $this->customer_model->get_customerdetails($withdrawal['userId']);
            $previousBalance = isset($userDoc['Earning']) ? (float)$userDoc['Earning'] : 0;
            $newBalance = $previousBalance + (float)$withdrawal['amount'];
            
            // Create WalletTransaction
            $transactionId = time() . rand();
            $walletTransaction = array(
                'action' => 'withdrawal_payout',
                'amount' => (float)$withdrawal['amount'],
                'createdAt' => time(),
                'createdAtMs' => time() * 1000,
                'currency' => 'USD',
                'newBalance' => $previousBalance,
                'previousBalance' => $newBalance,
                'processedBy' => 'admin',
                'processedByName' => $this->session->userdata('name'),
                'reason' => 'Withdrawal approved - Account: ' . $withdrawal['accountNumber'],
                'status' => 'completed',
                'userId' => $withdrawal['userId'],
                'withdrawalId' => $withdrawalId
            );
            
            // Add to WalletTransactions collection
            $this->common->adddatamodel('WalletTransactions', $transactionId, $walletTransaction);
            
            // Update withdrawal status
           // $this->common->updatedatamodel('Withdraws', $withdrawalId, array('status' => 'approved', 'processedAt' => time() * 1000));
            $this->common->deletedatamodel('Withdraws', $withdrawalId);
            // Update user balance
//            $this->common->updatedatamodel('Users', $withdrawal['userId'], array('balance' => $newBalance));
            
            // Send push notification
            $this->sendNotification(
                $withdrawal['userId'],
                'Withdrawal Approved',
                'Your withdrawal request of $' . number_format($withdrawal['amount'], 2) . ' has been approved and processed.'
            );
            
            echo json_encode(array('status' => true, 'message' => 'Withdrawal approved successfully'));
        } catch (Exception $e) {
            echo json_encode(array('status' => false, 'message' => 'Error: ' . $e->getMessage()));
        }
    }

    /**
     * Reject withdrawal request
     */
    public function rejectWithdrawal()
    {
        $withdrawalId = $this->input->post('withdrawalId');
        $reason = $this->input->post('reason');
        
        if (empty($withdrawalId)) {
            echo json_encode(array('status' => false, 'message' => 'Withdrawal ID is required'));
            return;
        }
        
        try {
            // Get withdrawal details
            $withdrawals = $this->common->readdatafromcollectionwhereclause('Withdraws');
            
            if (!isset($withdrawals[$withdrawalId])) {
                echo json_encode(array('status' => false, 'message' => 'Withdrawal not found'));
                return;
            }
            
            $withdrawal = $withdrawals[$withdrawalId];
            
            // Check if already processed
            if (isset($withdrawal['status']) && $withdrawal['status'] !== 'pending') {
                echo json_encode(array('status' => false, 'message' => 'Withdrawal already processed'));
                return;
            }
            
            // Get user current earning
            $userDoc = $this->customer_model->get_customerdetails($withdrawal['userId']);
            $currentEarning = isset($userDoc['Earning']) ? (float)$userDoc['Earning'] : 0;
            $newEarning = $currentEarning + (float)$withdrawal['amount'];
            
            // Create WalletTransaction for rejection (refund)
            $transactionId = time() . rand();
            $rejectionReason = !empty($reason) ? $reason : 'Rejected by admin';
            $walletTransaction = array(
                'action' => 'withdrawal_rejected',
                'amount' => (float)$withdrawal['amount'],
                'createdAt' => time(),
                'createdAtMs' => time() * 1000,
                'currency' => 'USD',
                'newBalance' => $newEarning,
                'previousBalance' => $currentEarning,
                'processedBy' => 'admin',
                'processedByName' => $this->session->userdata('name'),
                'reason' => 'Withdrawal rejected - Refunded to earnings. Reason: ' . $rejectionReason,
                'status' => 'refunded',
                'userId' => $withdrawal['userId'],
                'withdrawalId' => $withdrawalId,
                'rejectionReason' => $rejectionReason
            );
            
            // Add to WalletTransactions collection
            $this->common->adddatamodel('WalletTransactions', $transactionId, $walletTransaction);
            
            // Update withdrawal status
            $this->common->updatedatamodel('Withdraws', $withdrawalId, array(
                'status' => 'rejected',
                'processedAt' => time() * 1000,
                'rejectionReason' => $rejectionReason
            ));
            
            // Refund amount to user earning
            $this->common->updatedatamodel('Users', $withdrawal['userId'], array('Earning' => $newEarning));
            
            // Send push notification
            $notificationMessage = 'Your withdrawal request of $' . number_format($withdrawal['amount'], 2) . ' has been rejected.';
            if (!empty($reason)) {
                $notificationMessage .= ' Reason: ' . $reason;
            }
            
            $this->sendNotification(
                $withdrawal['userId'],
                'Withdrawal Rejected',
                $notificationMessage
            );
            
            echo json_encode(array('status' => true, 'message' => 'Withdrawal rejected successfully'));
        } catch (Exception $e) {
            echo json_encode(array('status' => false, 'message' => 'Error: ' . $e->getMessage()));
        }
    }

    /**
     * Send push notification to user
     */
    private function sendNotification($userId, $title, $message)
    {
        try {
            // Get user FCM token
            $userDoc = $this->customer_model->get_customerdetails($userId);
            
            if (!isset($userDoc['token']) || empty($userDoc['token'])) {
                log_message('info', 'No FCM token found for user: ' . $userId);
                return false;
            }
            
            // Use Firebase Messaging SDK
            $firebase = $this->firebase->init();
            $messaging = $firebase->createMessaging();
            
            $notification = \Kreait\Firebase\Messaging\Notification::create($title, $message);
            
            $cloudMessage = \Kreait\Firebase\Messaging\CloudMessage::withTarget('token', $userDoc['token'])
                ->withNotification($notification)
                ->withData([
                    'type' => 'withdrawal',
                    'title' => $title,
                    'body' => $message
                ]);
            
            $messaging->send($cloudMessage);
            
            return true;
        } catch (Exception $e) {
            log_message('error', 'Failed to send notification: ' . $e->getMessage());
            return false;
        }
    }
}

