<?php
// app/Services/CalendarService.php - Calendar & Availability Management

class CalendarService {
    private $db;
    
    public function __construct() {
        $this->db = Database::getInstance();
    }
    
    /**
     * Check if item is available for date range
     */
    public function isAvailable($item_id, $start_date, $end_date) {
        // Get item details
        $item_sql = "SELECT quantity, available_quantity FROM items WHERE id = ?";
        $item = $this->db->fetch($item_sql, [$item_id]);
        
        if (!$item || $item['available_quantity'] <= 0) {
            return false;
        }
        
        // Check calendar for each date in range
        $dates = $this->getDateRange($start_date, $end_date);
        
        foreach ($dates as $date) {
            $sql = "SELECT SUM(quantity_booked) as total_booked 
                    FROM availability_calendar 
                    WHERE item_id = ? AND date = ? AND status = 'booked'";
            
            $result = $this->db->fetch($sql, [$item_id, $date]);
            $booked = $result['total_booked'] ?? 0;
            
            // If any date has no availability, return false
            if ($booked >= $item['quantity']) {
                return false;
            }
            
            // Check for blocked dates
            $blocked_sql = "SELECT COUNT(*) as count 
                           FROM availability_calendar 
                           WHERE item_id = ? AND date = ? AND status = 'blocked'";
            
            $blocked_result = $this->db->fetch($blocked_sql, [$item_id, $date]);
            
            if ($blocked_result['count'] > 0) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Book dates for an order
     */
    public function bookDates($item_id, $order_id, $start_date, $end_date, $quantity = 1) {
        $this->db->beginTransaction();
        
        try {
            $dates = $this->getDateRange($start_date, $end_date);
            
            foreach ($dates as $date) {
                // Check if date already exists in calendar
                $check_sql = "SELECT id, quantity_booked FROM availability_calendar 
                             WHERE item_id = ? AND date = ? AND status = 'booked'";
                $existing = $this->db->fetch($check_sql, [$item_id, $date]);
                
                if ($existing) {
                    // Update existing booking
                    $update_sql = "UPDATE availability_calendar 
                                  SET quantity_booked = quantity_booked + ? 
                                  WHERE id = ?";
                    $this->db->execute($update_sql, [$quantity, $existing['id']]);
                } else {
                    // Create new booking
                    $insert_sql = "INSERT INTO availability_calendar 
                                  (item_id, order_id, date, status, quantity_booked, created_at) 
                                  VALUES (?, ?, ?, 'booked', ?, NOW())";
                    $this->db->execute($insert_sql, [$item_id, $order_id, $date, $quantity]);
                }
            }
            
            // Update item available quantity
            $this->updateItemAvailability($item_id);
            
            $this->db->commit();
            return true;
            
        } catch (Exception $e) {
            $this->db->rollback();
            log_message("Calendar booking error: " . $e->getMessage(), 'error');
            return false;
        }
    }
    
    /**
     * Release booked dates (when order is cancelled)
     */
    public function releaseDates($order_id) {
        $this->db->beginTransaction();
        
        try {
            // Get order details
            $order_sql = "SELECT item_id FROM orders WHERE id = ?";
            $order = $this->db->fetch($order_sql, [$order_id]);
            
            if (!$order) {
                throw new Exception("Order not found");
            }
            
            // Delete calendar entries
            $delete_sql = "DELETE FROM availability_calendar 
                          WHERE order_id = ? AND status = 'booked'";
            $this->db->execute($delete_sql, [$order_id]);
            
            // Update item available quantity
            $this->updateItemAvailability($order['item_id']);
            
            $this->db->commit();
            return true;
            
        } catch (Exception $e) {
            $this->db->rollback();
            log_message("Calendar release error: " . $e->getMessage(), 'error');
            return false;
        }
    }
    
    /**
     * Block dates (vendor can manually block dates)
     */
    public function blockDates($item_id, $start_date, $end_date) {
        $dates = $this->getDateRange($start_date, $end_date);
        
        foreach ($dates as $date) {
            // Check if date already blocked
            $check_sql = "SELECT id FROM availability_calendar 
                         WHERE item_id = ? AND date = ? AND status = 'blocked'";
            $existing = $this->db->fetch($check_sql, [$item_id, $date]);
            
            if (!$existing) {
                $insert_sql = "INSERT INTO availability_calendar 
                              (item_id, date, status, created_at) 
                              VALUES (?, ?, 'blocked', NOW())";
                $this->db->execute($insert_sql, [$item_id, $date]);
            }
        }
        
        $this->updateItemAvailability($item_id);
        
        return true;
    }
    
    /**
     * Unblock dates
     */
    public function unblockDates($item_id, $start_date, $end_date) {
        $dates = $this->getDateRange($start_date, $end_date);
        
        foreach ($dates as $date) {
            $delete_sql = "DELETE FROM availability_calendar 
                          WHERE item_id = ? AND date = ? AND status = 'blocked'";
            $this->db->execute($delete_sql, [$item_id, $date]);
        }
        
        $this->updateItemAvailability($item_id);
        
        return true;
    }
    
    /**
     * Calculate rental days
     */
    public function calculateRentalDays($start_date, $end_date) {
        $start = new DateTime($start_date);
        $end = new DateTime($end_date);
        $diff = $start->diff($end);
        
        // Add 1 to include both start and end date
        return $diff->days + 1;
    }
    
    /**
     * Calculate rental price
     */
    public function calculatePrice($item_id, $start_date, $end_date) {
        $item_sql = "SELECT price_per_day, security_deposit FROM items WHERE id = ?";
        $item = $this->db->fetch($item_sql, [$item_id]);
        
        if (!$item) {
            return null;
        }
        
        $rental_days = $this->calculateRentalDays($start_date, $end_date);
        $subtotal = $item['price_per_day'] * $rental_days;
        $platform_fee = ($subtotal * PLATFORM_COMMISSION) / 100;
        
        return [
            'rental_days' => $rental_days,
            'price_per_day' => $item['price_per_day'],
            'subtotal' => $subtotal,
            'security_deposit' => $item['security_deposit'],
            'platform_fee' => $platform_fee,
            'total_amount' => $subtotal + $item['security_deposit']
        ];
    }
    
    /**
     * Update item available quantity based on calendar
     */
    private function updateItemAvailability($item_id) {
        // Get item total quantity
        $item_sql = "SELECT quantity FROM items WHERE id = ?";
        $item = $this->db->fetch($item_sql, [$item_id]);
        
        if (!$item) {
            return false;
        }
        
        // Get current bookings for today onwards
        $today = date('Y-m-d');
        $sql = "SELECT COALESCE(MAX(quantity_booked), 0) as max_booked
                FROM availability_calendar
                WHERE item_id = ? 
                AND date >= ? 
                AND status = 'booked'";
        
        $result = $this->db->fetch($sql, [$item_id, $today]);
        $max_booked = $result['max_booked'] ?? 0;
        
        $available = max(0, $item['quantity'] - $max_booked);
        
        // Update item available quantity
        $update_sql = "UPDATE items SET available_quantity = ? WHERE id = ?";
        return $this->db->execute($update_sql, [$available, $item_id]);
    }
    
    /**
     * Get date range between two dates
     */
    private function getDateRange($start_date, $end_date) {
        $dates = [];
        $current = new DateTime($start_date);
        $end = new DateTime($end_date);
        
        while ($current <= $end) {
            $dates[] = $current->format('Y-m-d');
            $current->modify('+1 day');
        }
        
        return $dates;
    }
}