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

class Orders extends CI_Controller {

	function __construct()
	{
		parent::__construct();
        $this->load->helper('url');
        $this->load->library('session');
        $this->load->model('common');
    }

    /**
     * List all bookings with filters
     */
	public function index()
	{
        // Get filter parameters
        $filterStatus = $this->input->get('filter_status');
        $filterServiceType = $this->input->get('filter_service_type');
        $filterDateFrom = $this->input->get('filter_date_from');
        $filterDateTo = $this->input->get('filter_date_to');
        
        // Get all bookings from Bookings collection
        $allBookings = $this->common->readdatafromcollectionwhereclause('Bookings');
        
        // Apply filters
        $filteredBookings = array();
        foreach ($allBookings as $bookingId => $booking) {
            // Filter by status
            if ($filterStatus && $filterStatus != 'all') {
                $bookingStatus = isset($booking['status']) ? strtolower($booking['status']) : 'pending';
                if ($bookingStatus != strtolower($filterStatus)) {
                        continue;
                }
            }
            
            // Filter by service type
            if ($filterServiceType && $filterServiceType != 'all') {
                $serviceType = isset($booking['service_type']) ? strtoupper($booking['service_type']) : '';
                if ($serviceType != strtoupper($filterServiceType)) {
                    continue;
                }
            }
            
            // Filter by date range (use bookingDate, fallback to pickupDate)
            if ($filterDateFrom || $filterDateTo) {
                $bookingDate = isset($booking['bookingDate']) ? $booking['bookingDate'] : (isset($booking['pickupDate']) ? $booking['pickupDate'] : 0);
                
                if ($filterDateFrom) {
                    $fromTimestamp = strtotime($filterDateFrom) * 1000;
                    if ($bookingDate < $fromTimestamp) {
                        continue;
                    }
                }
                
                if ($filterDateTo) {
                    $toTimestamp = strtotime($filterDateTo . ' 23:59:59') * 1000;
                    if ($bookingDate > $toTimestamp) {
                        continue;
                    }
                }
            }
            
            $filteredBookings[$bookingId] = $booking;
        }
        
        // Sort by date (newest first) - use bookingDate, fallback to pickupDate
        usort($filteredBookings, function($a, $b) {
            $dateA = isset($a['bookingDate']) ? $a['bookingDate'] : (isset($a['pickupDate']) ? $a['pickupDate'] : 0);
            $dateB = isset($b['bookingDate']) ? $b['bookingDate'] : (isset($b['pickupDate']) ? $b['pickupDate'] : 0);
            return $dateB - $dateA;
        });
        
        // Enhance booking data with user information
        $enhancedBookings = $this->enhanceBookingData($filteredBookings);
        
        $data['orders'] = $enhancedBookings; // Keep variable name 'orders' for view compatibility
        $data['filterStatus'] = $filterStatus;
        $data['filterServiceType'] = $filterServiceType;
        $data['filterDateFrom'] = $filterDateFrom;
        $data['filterDateTo'] = $filterDateTo;
        
        $this->template->template_render('orders', $data);
    }
    
    /**
     * Enhance booking data with user and driver information
     */
    private function enhanceBookingData($bookings)
    {
        foreach ($bookings as $bookingId => &$booking) {
            $booking['bookingId'] = $bookingId;
            // Get user/customer information
            if (isset($booking['userId'])) {
                $user = $this->common->readdatadocument('Users', $booking['userId']);
                if (!empty($user)) {
                    $booking['userName'] = isset($user['userName']) ? $user['userName'] : 'Unknown User';
                    $booking['userEmail'] = isset($user['email']) ? $user['email'] : '';
                    $booking['userImage'] = isset($user['image']) ? $user['image'] : '';
                }
            }
            
            // Get driver information
            if (isset($booking['driverId'])) {
                $driver = $this->common->readdatadocument('Users', $booking['driverId']);
                if (!empty($driver)) {
                    $booking['driverName'] = isset($driver['userName']) ? $driver['userName'] : 'Unknown Driver';
                    $booking['driverEmail'] = isset($driver['email']) ? $driver['email'] : '';
                    $booking['driverImage'] = isset($driver['image']) ? $driver['image'] : '';
                }
            }
            
            // Get vehicle information
            if (isset($booking['vehicle']) && is_array($booking['vehicle']) && isset($booking['vehicle']['id'])) {
                $vehicleId = $booking['vehicle']['id'];
                // If you have a Vehicles collection, you can fetch additional vehicle details here
                $booking['vehicleName'] = isset($booking['vehicle']['name']) ? $booking['vehicle']['name'] : 'Unknown Vehicle';
                $booking['vehicleImage'] = isset($booking['vehicle']['image']) ? $booking['vehicle']['image'] : '';
            }
            
            // Format pickup address
            if (isset($booking['pickUp']) && is_array($booking['pickUp'])) {
                $booking['pickupAddress'] = isset($booking['pickUp']['address']) ? $booking['pickUp']['address'] : 'Address not specified';
                $booking['pickupLat'] = isset($booking['pickUp']['lat']) ? $booking['pickUp']['lat'] : 0;
                $booking['pickupLng'] = isset($booking['pickUp']['lng']) ? $booking['pickUp']['lng'] : 0;
            }
            
            // Format destinations
            if (isset($booking['destinations']) && is_array($booking['destinations'])) {
                $destinationsList = array();
                foreach ($booking['destinations'] as $destination) {
                    if (isset($destination['address'])) {
                        $destinationsList[] = $destination['address'];
                    }
                }
                $booking['destinationsList'] = $destinationsList;
                $booking['destinationsCount'] = count($destinationsList);
            }
            
            // Format price (convert string to float for calculations)
            if (isset($booking['price'])) {
                $booking['priceFloat'] = floatval($booking['price']);
                $booking['priceFormatted'] = '$' . number_format($booking['priceFloat'], 2);
            }
        }
        
        return $bookings;
    }

    /**
     * View booking details
     */
    public function view()
    {
        $bookingId = $this->uri->segment(3);
        if (!$bookingId) {
            redirect(base_url('orders'));
            return;
        }

        $booking = $this->common->readdatadocument('Bookings', $bookingId);
        if (empty($booking)) {
            $this->session->set_flashdata('warningmessage', 'Booking not found');
            redirect(base_url('orders'));
            return;
        }

        // Get user/customer data
        if (isset($booking['userId'])) {
            $data['customer'] = $this->common->readdatadocument('Users', $booking['userId']);
        }

        // Get driver data
        if (isset($booking['driverId'])) {
            $data['driver'] = $this->common->readdatadocument('Users', $booking['driverId']);
        }

        // Enhance booking data with formatted information
        if (isset($booking['pickUp']) && is_array($booking['pickUp'])) {
            $booking['pickupAddress'] = isset($booking['pickUp']['address']) ? $booking['pickUp']['address'] : 'Address not specified';
            $booking['pickupLat'] = isset($booking['pickUp']['lat']) ? $booking['pickUp']['lat'] : 0;
            $booking['pickupLng'] = isset($booking['pickUp']['lng']) ? $booking['pickUp']['lng'] : 0;
        }

        // Format destinations
        if (isset($booking['destinations']) && is_array($booking['destinations'])) {
            $destinationsList = array();
            foreach ($booking['destinations'] as $destination) {
                if (isset($destination['address'])) {
                    $destinationsList[] = array(
                        'address' => $destination['address'],
                        'lat' => isset($destination['lat']) ? $destination['lat'] : 0,
                        'lng' => isset($destination['lng']) ? $destination['lng'] : 0
                    );
                }
            }
            $booking['destinationsList'] = $destinationsList;
            $booking['destinationsCount'] = count($destinationsList);
        }

        // Format price
        if (isset($booking['price'])) {
            $booking['priceFloat'] = floatval($booking['price']);
            $booking['priceFormatted'] = '$' . number_format($booking['priceFloat'], 2);
        }

        // Get vehicle information
        if (isset($booking['vehicle']) && is_array($booking['vehicle'])) {
            $booking['vehicleName'] = isset($booking['vehicle']['name']) ? $booking['vehicle']['name'] : 'Unknown Vehicle';
            $booking['vehicleImage'] = isset($booking['vehicle']['image']) ? $booking['vehicle']['image'] : '';
            $booking['vehicleDescription'] = isset($booking['vehicle']['description']) ? $booking['vehicle']['description'] : '';
            $booking['vehiclePrice'] = isset($booking['vehicle']['price']) ? $booking['vehicle']['price'] : '';
        }

        $data['order'] = $booking; // Keep variable name 'order' for view compatibility
        $data['orderId'] = $bookingId; // Keep variable name for view compatibility
        
        $this->template->template_render('order_view', $data);
    }

    /**
     * Update booking status
     * When booking is marked as completed, automatically process loyalty points
     */
    public function updatestatus()
    {
        $bookingId = $this->input->post('orderId'); // Keep parameter name 'orderId' for compatibility
        $status = $this->input->post('status');

        if (!$bookingId || !$status) {
            if ($this->input->is_ajax_request()) {
                echo json_encode(array('success' => false, 'message' => 'Booking ID and status are required'));
		} else {
                $this->session->set_flashdata('warningmessage', 'Booking ID and status are required');
                redirect(base_url('orders'));
            }
            return;
        }

        // Get current booking to check previous status
        $currentBooking = $this->common->readdatadocument('Bookings', $bookingId);
        if (empty($currentBooking)) {
            if ($this->input->is_ajax_request()) {
                echo json_encode(array('success' => false, 'message' => 'Booking not found'));
            } else {
                $this->session->set_flashdata('warningmessage', 'Booking not found');
                redirect(base_url('orders'));
            }
            return;
        }

        $previousStatus = isset($currentBooking['status']) ? strtolower($currentBooking['status']) : '';

        $data = array('status' => $status);
        $response = $this->common->updatedatamodel('Bookings', $bookingId, $data);

		if ($response) {
            // If booking is being marked as completed/rideComplete, process loyalty points
            $statusLower = strtolower($status);
            $isCompleted = in_array($statusLower, array('completed', 'ridecomplete', 'delivered', 'rated'));
            $wasNotCompleted = !in_array($previousStatus, array('completed', 'ridecomplete', 'delivered', 'rated'));

            if ($isCompleted && $wasNotCompleted) {
                // Process loyalty points for completed booking
                $this->processLoyaltyPointsForBooking($bookingId);
            }

            if ($this->input->is_ajax_request()) {
                echo json_encode(array('success' => true, 'message' => 'Booking status updated successfully'));
		} else {
                $this->session->set_flashdata('successmessage', 'Booking status updated successfully');
                redirect(base_url('orders/view/' . $bookingId));
            }
		} else {
            if ($this->input->is_ajax_request()) {
                echo json_encode(array('success' => false, 'message' => 'Failed to update booking status'));
            } else {
                $this->session->set_flashdata('warningmessage', 'Failed to update booking status');
                redirect(base_url('orders/view/' . $bookingId));
            }
        }
    }

    /**
     * Process loyalty points for a completed booking
     * @param string $bookingId Booking ID
     * @return bool Success status
     */
    private function processLoyaltyPointsForBooking($bookingId)
    {
        $this->load->helper('loyalty');
        
        // Get booking
        $booking = $this->common->readdatadocument('Bookings', $bookingId);
        if (empty($booking)) {
            log_message('error', 'Loyalty: Booking not found - ' . $bookingId);
            return false;
        }
        
        // Check if already processed
        $transactions = $this->common->readdatafromcollectionwhereclause('LoyaltyTransactions');
        $alreadyProcessed = false;
        if (!empty($transactions)) {
            foreach ($transactions as $transaction) {
                if (isset($transaction['orderId']) && $transaction['orderId'] == $bookingId && 
                    isset($transaction['type']) && $transaction['type'] == 'earned') {
                    $alreadyProcessed = true;
                    break;
                }
            }
        }
        
        if ($alreadyProcessed) {
            log_message('info', 'Loyalty: Points already processed for booking - ' . $bookingId);
            return false;
        }
        
        // Get customer ID (userId in Bookings collection)
        $customerId = isset($booking['userId']) ? $booking['userId'] : null;
        if (!$customerId) {
            log_message('error', 'Loyalty: User ID not found in booking - ' . $bookingId);
            return false;
        }
        
        // Verify customer exists and is a customer
        $customer = $this->common->readdatadocument('Users', $customerId);
        if (empty($customer)) {
            log_message('error', 'Loyalty: Customer not found - ' . $customerId);
            return false;
        }
        
        $userRole = isset($customer['userRole']) ? $customer['userRole'] : '';
        if ($userRole != 'user') {
            log_message('info', 'Loyalty: User is not a customer - ' . $customerId);
            return false;
        }
        
        // Get booking total (price is a string in Bookings)
        $bookingTotal = 0;
        if (isset($booking['price'])) {
            $bookingTotal = floatval($booking['price']);
        }
        
        if ($bookingTotal <= 0) {
            log_message('error', 'Loyalty: Invalid booking total for booking - ' . $bookingId);
            return false;
        }
        
        // Check if loyalty is enabled
        $settings = get_loyalty_settings($this->common);
        if (empty($settings) || (isset($settings['loyaltyEnabled']) && !$settings['loyaltyEnabled'])) {
            log_message('info', 'Loyalty: Program is disabled');
            return false;
        }
        
        // Calculate loyalty points
        $pointsCalculation = calculate_loyalty_points($bookingTotal, $customerId, $bookingId, $this->common);
        $pointsEarned = isset($pointsCalculation['points']) ? intval($pointsCalculation['points']) : 0;
        
        if ($pointsEarned <= 0) {
            log_message('info', 'Loyalty: No points to award for booking - ' . $bookingId);
            return false;
        }
        
        // Build description with breakdown
        $breakdown = isset($pointsCalculation['breakdown']) ? $pointsCalculation['breakdown'] : array();
        $description = 'Points earned from booking #' . $bookingId;
        if (!empty($breakdown)) {
            $bonusDescriptions = array();
            foreach ($breakdown as $bonus) {
                if (isset($bonus['description'])) {
                    $bonusDescriptions[] = $bonus['description'];
                }
            }
            if (!empty($bonusDescriptions)) {
                $description .= ' (' . implode(', ', $bonusDescriptions) . ')';
            }
        }
        
        // Award loyalty points
        $awardResult = award_loyalty_points($customerId, $pointsEarned, 'earned', $bookingId, $description, $this->common);
        
        if (!$awardResult) {
            log_message('error', 'Loyalty: Failed to award points for booking - ' . $bookingId);
            return false;
        }
        
        // Mark booking as processed
        $updateData = array(
            'loyaltyPointsProcessed' => true,
            'loyaltyPointsEarned' => $pointsEarned,
            'loyaltyPointsProcessedAt' => time() * 1000
        );
        $this->common->updatedatamodel('Bookings', $bookingId, $updateData);
        
        log_message('info', 'Loyalty: Successfully processed ' . $pointsEarned . ' points for booking - ' . $bookingId);
        return true;
    }

    /**
     * Filter orders by status (legacy method - redirects to index with filter)
     */
    public function filter()
    {
        $status = $this->uri->segment(3);
        redirect(base_url('orders?filter_status=' . ($status ? $status : 'all')));
	}
}
